home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
tptools.zip
/
FIRSTED.ZIP
/
EDEDIT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1987-12-21
|
30KB
|
1,103 lines
{ EDEDIT.PAS
ED 4.0
Copyright (c) 1985, 87 by Borland International, Inc. }
{$I eddirect.inc}
unit EdEdit;
{-Basic text editing commands}
interface
uses
crt, {Basic video operations - standard unit}
Dos, {DOS calls - standard unit}
Errors, {Runtime error handler}
EdVars, {Global types and declarations}
EdScrn1, {Fast screen writing routines}
EdString, {String primitives}
EdPtrOp, {Primitive pointer operations}
EdCmds, {Maps keystrokes to commands}
int24, {DOS critical error handler}
Message, {Message system}
EdUser, {User keyboard input, line editing and error reporting}
EdMemOp, {Text buffer allocation and deallocation}
EdBack, {Background processes}
EdScrn2; {Editor screen updating}
procedure EdUpLine;
{-Process up line command}
procedure EdDownLine;
{-Process down line command}
procedure EdLeftLine;
{-Move cursor to left edge of line}
procedure EdRightLine;
{-Move cursor to right edge of line}
procedure EdWindowBottomFile;
{-Move cursor to bottom of file}
procedure EdDeleteRightChar;
{-Process delete right character command}
procedure EdDeleteLeftChar;
{-Process delete left character command}
procedure EdNewLine;
{-Process <Enter> key}
procedure EdInsertLine;
{-Process insert line command}
procedure EdJumpMarker(M : BlockMarker);
{-Move cursor to marker at line,column}
procedure EdLeftChar;
{-Process left character command}
procedure EdRightChar;
{-Process right character command}
procedure EdScrollUp;
{-Process scroll up command}
procedure EdScrollDown;
{-Process scroll down command}
procedure EdUpPage;
{-Process up page command}
procedure EdDownPage;
{-Process down page command}
procedure EdLeftWord;
{-Move cursor to previous word}
procedure EdRightWord;
{-Advance cursor to next word}
procedure EdDeleteRightWord;
{-Process delete right word command}
procedure EdProcesstext(Ch : Char);
{-Process text input}
procedure EdInsertCtrlChar;
{-Insert literal character as text into file}
procedure EdUndo;
{-Process UNDO command}
procedure EdRestoreCurrentLine;
{-Restore text and flags of current line}
procedure EdDeleteLine;
{-Process delete line command}
procedure EdDeleteLineRight;
{-Kill text to right of cursor}
procedure EdFlagExit;
{-Set flag to exit editor}
procedure EdSysInfo;
{-Display editor information}
procedure EdSizeWindow;
{-Interactively size the current window}
{==========================================================================}
implementation
{***}
procedure EdUpLine;
{-Process up line command}
begin {EdUpLine}
with CurWin^ do
if EdPtrNotNil(CurLine^.Backlink) then begin
Dec(Clineno);
EdBackPtr(CurLine);
if LineNo = 1 then begin
EdBackPtr(TopLine);
TempScroll := 1;
end else begin
TempScroll := 0;
Dec(LineNo);
end;
end else
TempScroll := 0;
end; {EdUpLine}
{***}
procedure EdDownLine;
{-Process down line command}
begin {EdDownLine}
with CurWin^ do
if EdPtrNotNil(CurLine^.FwdLink) then begin
Inc(Clineno);
EdFwdPtr(CurLine);
if LineNo > (LastLineNo-FirstTextNo) then begin
EdFwdPtr(TopLine);
TempScroll := -1;
end else begin
TempScroll := 0;
Inc(LineNo);
end;
end else
TempScroll := 0;
end; {EdDownLine}
procedure EdRightLine;
{-Move cursor to right edge of line}
begin {EdRightLine}
with CurWin^ do begin
ColNo := Succ(EdTextLength(CurLine));
if ColNo > MaxLineLength then
ColNo := MaxLineLength;
end;
end; {EdRightLine}
procedure EdDeleteRightChar;
{-Process delete right character command}
begin {EdDeleteRightChar}
with CurWin^ do begin
if ColNo > CurLine^.Bufflen then
Exit;
Modified := True;
with CurLine^ do begin
if ColNo < Bufflen then
Move(Txt^[Succ(ColNo)], Txt^[ColNo], Bufflen-ColNo);
Txt^[Bufflen] := Blank;
end;
{Fix up markers}
EdFixBlockInsertedSpace(CurLine, ColNo, -1);
EdCheckNoMarker;
EdFixMarkInsertedSpace(CurLine, ColNo-1, -1);
end;
end; {EdDeleteRightChar}
{***}
procedure EdDeleteLeftChar;
{-Process delete left character command}
begin {EdDeleteLeftChar}
with CurWin^ do begin
if ColNo = 1 then begin
{Beginning of line}
if EdPtrNotNil(CurLine^.Backlink) then begin
Modified := True;
{Move to end of previous line and join}
EdUpLine;
EdRightLine;
EdJoinline;
EdRealign;
{Force screen to be fully updated}
IntrFlag := NoInterr;
end;
end else begin
{Middle or end of line}
Dec(ColNo);
EdDeleteRightChar;
end;
end;
end; {EdDeleteLeftChar}
procedure EdNewLine;
{-Process <Enter> key}
begin {EdNewLine}
with CurWin^ do begin
if InsertFlag or EdPtrIsNil(CurLine^.FwdLink) then begin
EdNewLinePrimitive;
EdRealign;
end else begin
EdDownLine;
ColNo := 1;
end;
LeftEdge := 1;
end;
end; {EdNewLine}
procedure EdInsertLine;
{-Process insert line command}
var
CurL : PlineDesc;
CurC : Integer;
begin {EdInsertLine}
{Save cursor position}
with CurWin^ do begin
CurL := CurLine;
CurC := ColNo;
end;
{Use Newline to do the work}
EdNewLinePrimitive;
if GotError then
Exit;
{Restore cursor position}
with CurWin^ do begin
CurLine := CurL;
ColNo := CurC;
end;
EdRealign;
end; {EdInsertLine}
{***}
procedure EdJumpMarker(M : BlockMarker);
{-Move cursor to marker at line,column}
var
W : PwinDesc;
Mline : PlineDesc;
begin {Edjumpmarker}
Mline := M.Line;
if EdPtrIsNil(Mline) then begin
EdErrormsg(29);
Exit;
end;
{Determine which window holds the marked line}
W := EdFindWindow(Mline);
if EdPtrIsNil(W) then begin
{Mark is not in displayable text}
EdErrormsg(30);
Exit;
end;
CurWin := W;
with CurWin^ do begin
{See if marker is towards top of file, but on current screen}
while EdPtrNotNil(CurLine^.Backlink) and (CurLine <> TopLine) and (CurLine <> Mline) do
EdUpLine;
{See if marker is towards end of file}
while EdPtrNotNil(CurLine^.FwdLink) and (CurLine <> Mline) do
EdDownLine;
if CurLine <> Mline then begin
{Marker must be above top of screen}
TopLine := Mline;
CurLine := Mline;
LineNo := 1;
end;
{Set column number}
ColNo := M.Col;
end;
end; {Edjumpmarker}
procedure EdLeftChar;
{-Process left character command}
begin {EdLeftChar}
with CurWin^ do
if ColNo > 1 then begin
Dec(ColNo);
if EditUsercommandInput = 0 then begin
EdHscrollOne(CurWin);
EdUpdateCursor;
EdUpdateStatusLine(CurWin);
end;
end;
end; {EdLeftChar}
procedure EdRightChar;
{-Process right character command}
begin {EdRightChar}
with CurWin^ do
if ColNo < MaxLineLength then begin
Inc(ColNo);
if EditUsercommandInput = 0 then begin
EdHscrollOne(CurWin);
EdUpdateCursor;
EdUpdateStatusLine(CurWin);
end;
end;
end; {EdRightChar}
{***}
procedure EdScrollUp;
{-Process scroll up command}
begin {EdScrollUp}
with CurWin^ do
if EdPtrNotNil(TopLine^.Backlink) then begin
EdBackPtr(TopLine);
if LineNo > (LastLineNo-FirstTextNo) then begin
Dec(Clineno);
EdBackPtr(CurLine);
end else
Inc(LineNo);
Inc(FullScroll);
end;
end; {EdScrollUp}
{***}
procedure EdScrollDown;
{-Process scroll down command}
begin {EdScrollDown}
with CurWin^ do
if EdPtrNotNil(TopLine^.FwdLink) then begin
EdFwdPtr(TopLine);
if LineNo = 1 then begin
Inc(Clineno);
EdFwdPtr(CurLine);
end else
Dec(LineNo);
Dec(FullScroll);
end;
end; {EdScrollDown}
{***}
procedure EdUpPage;
{-Process up page command}
var
PageSize, I : Integer;
begin {EdUpPage}
with CurWin^ do begin
PageSize := Succ(LastLineNo-FirstTextNo);
I := 1;
while (I < PageSize) and EdPtrNotNil(TopLine^.Backlink) do begin
{Back the screen up}
EdBackPtr(TopLine);
EdBackPtr(CurLine);
Dec(Clineno);
Inc(I);
end;
while (I < PageSize) do begin
{Back the cursor up if needed}
EdUpLine;
Inc(I);
end;
end;
end; {EdUpPage}
{***}
procedure EdDownPage;
{-Process down page command}
var
PageSize, I : Integer;
begin {EdDownPage}
with CurWin^ do begin
PageSize := Succ(LastLineNo-FirstTextNo);
I := 1;
while (I < PageSize) and EdPtrNotNil(TopLine^.FwdLink) do begin
EdFwdPtr(TopLine);
Inc(I);
if EdPtrIsNil(CurLine^.FwdLink) then
Dec(LineNo)
else begin
Inc(Clineno);
EdFwdPtr(CurLine);
end;
end;
end;
end; {EdDownPage}
{***}
procedure EdLeftWord;
{-Move cursor to previous word}
procedure EdBackOneLine;
{-Move cursor up to the end of the previous line}
begin {EdBackOneLine}
if EdPtrNotNil(CurWin^.CurLine^.Backlink) then begin
EdUpLine;
EdRightLine;
end;
end; {EdBackOneLine}
begin {EdLeftWord}
with CurWin^ do
if ColNo <= 1 then
{Beginning of line, move to end of previous line}
EdBackOneLine
else
with CurLine^ do begin
{Work within the current line}
EdMoveCursorIntoLine;
if (Txt^[ColNo] in Alphas) then begin
{Currently within a word}
Dec(ColNo);
if not(Txt^[ColNo] in Alphas) then
{Go to end of previous word}
while (ColNo > 0) and not(Txt^[ColNo] in Alphas) do
Dec(ColNo);
{Go to beginning of this word}
while (ColNo > 0) and (Txt^[ColNo] in Alphas) do
Dec(ColNo);
{Forward to next Alpha}
Inc(ColNo);
end else begin
{Currently between words}
{Go to end of previous word}
while (ColNo > 0) and not(Txt^[ColNo] in Alphas) do
Dec(ColNo);
if ColNo <> 0 then
{Go to begin of previous word}
while (ColNo > 0) and (Txt^[ColNo] in Alphas) do
Dec(ColNo);
Inc(ColNo);
end;
end;
end; {EdLeftWord}
{***}
procedure EdRightWord;
{-Advance cursor to next word}
begin {EdRightWord}
with CurWin^ do begin
if EdPtrIsNil(CurLine^.FwdLink) and (ColNo >= EdTextLength(CurLine)) then
Exit;
{Work within the current line buffer}
EdMoveCursorIntoLine;
with CurLine^ do
if (Txt^[ColNo] in Alphas) then begin
{Starting within a word}
while (ColNo <= Bufflen) and (Txt^[ColNo] in Alphas) do
{Advance to next non-alpha}
Inc(ColNo);
if (ColNo <= Bufflen) then begin
{Skip over spaces after the word}
while (ColNo <= Bufflen) and not(Txt^[ColNo] in Alphas) do
Inc(ColNo);
if ColNo > Bufflen then
{Rest of line was non-alpha, stop after last word}
EdRightLine;
end;
end else begin
{Starting in white space, get to next non-blank}
while (ColNo <= Bufflen) and not(Txt^[ColNo] in Alphas) do
{Advance to next non-space on this line}
Inc(ColNo);
if (ColNo <= Bufflen) then
{Found a non-blank}
Exit;
EdDownLine;
ColNo := 1;
end;
end;
end; {EdRightWord}
{***}
procedure EdDeleteRightWord;
{-Process delete right word command}
var
StartClass : Integer;
function EdClass : Integer;
var
Ch : Char;
begin {EdClass}
with CurWin^ do
Ch := CurLine^.Txt^[ColNo];
if Ch = Blank then
EdClass := 1
else if (Ch in Alphas) then
EdClass := 2
else
EdClass := 3
end; {EdClass}
begin {EdDeleteRightWord}
with CurWin^ do
if ColNo > EdTextLength(CurLine) then begin
{Join next line to end of this one}
Modified := True;
EdJoinline;
{Flag forces the newly joined line to be rebuffered for ^QL}
Blockop := True;
end else begin
if CurLine^.Txt^[ColNo] <> Blank then begin
{In a word - delete to next space}
StartClass := EdClass;
while (EdClass = StartClass) and (ColNo <= CurLine^.Bufflen) do
EdDeleteRightChar;
end;
{In white space - delete spaces}
while (CurLine^.Txt^[ColNo] = Blank) and (ColNo <= EdTextLength(CurLine)) do
EdDeleteRightChar;
end;
{Force screen to be fully updated}
IntrFlag := NoInterr;
end; {EdDeleteRightWord}
{***}
procedure EdProcesstext(Ch : Char);
{-Process text input}
label
ExitPoint;
var
Len : Integer;
begin {EdProcesstext}
with CurWin^ do begin
if ColNo >= MaxLineLength then
{Cursor sitting at maximum length, ignore further characters}
Exit;
with CurLine^ do begin
if InsertFlag then begin
{Insert mode, shift existing characters right}
if ColNo >= Bufflen then
Len := ColNo
else
Len := Succ(EdTextLength(CurLine));
if (Len >= Bufflen) then
{Text buffer is full, size it up - keep at least one blank at end}
if not EdSizeline(CurLine, Succ(Len), True) then
Exit;
{Shift existing text over one character}
Move(Txt^[ColNo], Txt^[Succ(ColNo)], Bufflen-ColNo);
{Fix up markers}
EdFixBlockInsertedSpace(CurLine, ColNo, 1);
EdFixMarkInsertedSpace(CurLine, ColNo, 1);
end else
{Overwrite mode}
if Succ(ColNo) >= Bufflen then
if not EdSizeline(CurLine, Succ(ColNo), True) then
Exit;
{Add new character}
Txt^[ColNo] := Ch;
end; {with Curline^}
ExitPoint:
Inc(ColNo);
Modified := True;
{Get out fast if macro is in progress}
if EditUsercommandInput = 0 then begin
{Assure horizontal scroll is up to date for this window}
EdHscrollOne(CurWin);
{Update the cursor}
EdUpdateCursor;
{Update the current line on screen}
EdUpdateLine(CurLine, Pred(FirstTextNo+LineNo), LeftEdge, LeftCol, AT);
{Update the status line}
EdUpdateStatusLine(CurWin);
{Assure rest of screen updated when there is time}
UpdateScreen := True;
end;
end;
end; {EdProcesstext}
procedure EdInsertCtrlChar;
{-Insert literal character as text into file}
begin {EdInsertCtrlChar}
{Let us see the ^P character}
EdDisplayCommandBuffer;
{And assure ^U will get through}
AbortEnable := False;
EdProcesstext(EdGetAnyChar);
end; {EdInsertCtrlChar}
procedure EdLeftLine;
{-Move cursor to left edge of line}
begin {EdLeftLine}
EdGotoColumn(1);
end; {EdLeftLine}
{***}
procedure EdWindowBottomFile;
{-Move cursor to bottom of file}
begin {EdWindowBottomFile}
while EdPtrNotNil(CurWin^.CurLine^.FwdLink) do
EdDownLine;
{Go to end of line}
EdRightLine;
end; {EdWindowBottomFile}
{***}
procedure EdUndo;
{-Process UNDO command}
var
P : PlineDesc;
begin {EdUndo}
{If either Undolimit or Undocount = 0, we don't have anything to undo}
if UndoLimit*UndoCount = 0 then
Exit;
{Put the line back into the editing environment}
Dec(UndoCount);
P := UndoStack;
EdFwdPtr(UndoStack);
if EdPtrIsNil(UndoStack) then
EdSetPtrNil(UndoEnd);
{Reset all flags}
P^.Flags := 0;
{Insert the line into the current text stream}
with CurWin^ do begin
Modified := True;
if EdPtrIsNil(TopLine^.Backlink) and EdPtrIsNil(TopLine^.FwdLink) and (EdTextLength(CurLine) = 0) then begin
{File is empty, don't insert, just copy}
{Size up topline if needed}
if EdSizeline(TopLine, Succ(P^.Bufflen), True) then
Move(P^.Txt^[1], TopLine^.Txt^[1], P^.Bufflen);
EdDesTextDesc(P);
end else begin
{Really insert the buffer}
P^.Backlink := CurLine^.Backlink;
if EdPtrNotNil(P^.Backlink) then
P^.Backlink^.FwdLink := P;
P^.FwdLink := CurLine;
CurLine^.Backlink := P;
if CurLine = TopLine then
{Keep Topline above Curline}
TopLine := P;
{Backup current line}
CurLine := P;
end;
end;
EdRealign;
end; {EdUndo}
procedure EdRestoreCurrentLine;
{-Restore text and flags of current line}
var
M : Integer;
begin {EdRestoreCurrentLine}
with CurWin^ do
{Assure something has been stored}
if CurLineBuf^.Bufflen <> 0 then begin
{Reset blocks and markers as needed}
if Blockfrom.Line = CurLine then
Blockfrom.Col := CurLineFrom.Col;
if Blockfrom.Line <> CurLineFrom.Line then begin
Blockfrom.Line := CurLineFrom.Line;
{Reset screen attributes}
EdOffblock;
end;
if Blockto.Line = CurLine then
Blockto.Col := CurLineTo.Col;
if Blockto.Line <> CurLineTo.Line then begin
Blockto.Line := CurLineTo.Line;
EdOffblock;
end;
if EdFlagSet(CurLine, InMark) and not(EdFlagSet(CurLineBuf, InMark)) then begin
{Text mark was added - reset it}
for M := 0 to MaxMarker do
if Marker[M].Line = CurLine then
EdSetPtrNil(Marker[M].Line);
{Any mark stolen from another line is lost}
end;
CurLine^.Flags := CurLineBuf^.Flags;
Move(CurLineBuf^.Txt^[1], CurLine^.Txt^[1], CurLineBuf^.Bufflen);
if CurLineBuf^.Bufflen < CurLine^.Bufflen then
{Line has grown in the meantime, so right fill with blanks}
FillChar(CurLine^.Txt^[Succ(CurLineBuf^.Bufflen)],
CurLine^.Bufflen-CurLineBuf^.Bufflen, Blank);
{Reset the cursor}
ColNo := CurLineCol;
LeftEdge := 1;
EdHscrollOne(CurWin);
{Restoring the line may have modified the file}
Modified := True;
end;
end; {EdRestoreCurrentLine}
{***}
procedure EdDeleteLine;
{-Process delete line command}
var
P : PlineDesc;
procedure EdDelline(P : PlineDesc);
{-Delete line from text stream}
begin {EdDelline}
{Check block limits}
if P = Blockfrom.Line then begin
if (P = Blockto.Line) then begin
{Remove block altogether}
EdSetPtrNil(Blockfrom.Line);
EdSetPtrNil(Blockto.Line);
end else begin
{Note p^.fwdlink cannot be nil in this condition}
Blockfrom.Line := P^.FwdLink;
Blockfrom.Col := 1;
end;
end else if P = Blockto.Line then begin
{Blockto is being deleted}
if EdPtrIsNil(P^.FwdLink) then begin
{Note that p^.backlink cannot be nil in this condition}
Blockto.Line := P^.Backlink;
Blockto.Col := Succ(EdTextLength(P^.Backlink));
end else begin
Blockto.Line := P^.FwdLink;
Blockto.Col := 1;
end;
end;
{Fix up topline, curline, lineno of any window now pointing to the line p}
EdFixUpWindowSpan(P);
{Put the line on undo stack if possible}
if EdPtrNotNil(P^.FwdLink) or (EdTextLength(P) > 0) then
EdPushUndo(P);
end; {EdDelline}
begin {EdDeleteLine}
with CurWin^ do begin
Modified := True;
P := CurLine;
if EdPtrIsNil(P^.FwdLink) then begin
{This is the only line or the last line in the file}
CurLine := EdMaktextdesc(1);
if GotError then
Exit;
CurLine^.Backlink := P^.Backlink;
EdSetPtrNil(CurLine^.FwdLink);
if EdPtrNotNil(P^.Backlink) then
P^.Backlink^.FwdLink := CurLine;
if P = TopLine then
TopLine := CurLine;
end else if EdPtrIsNil(P^.Backlink) then begin
{It's the first line in the file}
TopLine := CurLine^.FwdLink;
CurLine := TopLine;
EdSetPtrNil(TopLine^.Backlink);
end else begin
{In the middle of the file}
if P = TopLine then
EdFwdPtr(TopLine);
EdFwdPtr(CurLine);
CurLine^.Backlink := P^.Backlink;
P^.Backlink^.FwdLink := CurLine;
end;
EdDelline(P);
ColNo := 1;
end;
EdRealign;
{Force screen to fully update after this command}
IntrFlag := NoInterr;
end; {EdDeleteLine}
procedure EdDeleteLineRight;
{-Kill text to right of cursor}
var
M : Integer;
begin {EdDeleteLineRight}
with CurWin^ do begin
if ColNo > CurLine^.Bufflen then
Exit;
{Just blank out the text}
FillChar(CurLine^.Txt^[ColNo], Succ(CurLine^.Bufflen-ColNo), Blank);
Modified := True;
{Fix up markers}
if (Blockfrom.Line = CurLine) and (Blockfrom.Col > ColNo) then begin
EdClrFlag(CurLine, InBlock);
if (Blockto.Line = CurLine) or EdPtrIsNil(CurLine^.FwdLink) then begin
{whole block deleted}
EdSetPtrNil(Blockfrom.Line);
EdSetPtrNil(Blockto.Line);
end else begin
Blockfrom.Line := CurLine^.FwdLink;
Blockfrom.Col := 1;
end;
end;
if (Blockto.Line = CurLine) and (Blockto.Col > ColNo) then
Blockto.Col := ColNo;
if EdFlagSet(CurLine, InMark) then
for M := 0 to MaxMarker do
with Marker[M] do
if (Line = CurLine) and (Col > ColNo) then
Col := ColNo;
end;
end; {EdDeleteLineRight}
{***}
procedure EdFlagExit;
{-Set flag to exit editor}
begin {EdFlagExit}
Rundown := True;
if CleanupAtExit then begin
{Dispose of heap space used by text}
EdDeleteAllText(CurWin);
{Push window onto free list}
EdPushWindowStack(CurWin);
end;
end; {EdFlagExit}
{***}
procedure EdSysInfo;
{-Display editor information}
var
Ch : Char;
begin {EdSysInfo}
{Show version number and prompt for <Esc>}
EdWritePromptLine(EdGetMessage(343)+Version+'-'+EdGetMessage(305));
{Wait for <Esc>}
repeat
Ch := EdGetAnyChar;
until Abortcmd or (Ch = #27);
{Restore the screen}
EdWritePromptLine('');
end; {EdSysInfo}
{***}
procedure EdSizeWindow;
{-Interactively size the current window}
type
SizeCommands = (Bigger, Smaller, Accept, None);
var
TopEdge, Done : Boolean;
procedure EdGrowWindow(TopEdge : Boolean);
{-Increase size of current window by one line}
var
W : PwinDesc;
begin {EdGrowWindow}
{Two or more windows previously guaranteed open}
if TopEdge then begin
{Bottom Window}
{Add to top of window, taking it from previous window}
W := CurWin^.Backlink;
if (W^.LastLineNo-W^.FirstTextNo) < MinWindowLines then
Exit;
CurWin^.FirstLineNo := Pred(CurWin^.FirstLineNo);
W^.LastLineNo := Pred(W^.LastLineNo);
EdSetTextNo(CurWin);
end else begin
{Top or middle window}
{Add to bottom of window, taking it from next window}
W := CurWin^.FwdLink;
{Make sure the other window can be shrunk}
if (W^.LastLineNo-W^.FirstTextNo) < MinWindowLines then
Exit;
CurWin^.LastLineNo := Succ(CurWin^.LastLineNo);
W^.FirstLineNo := Succ(W^.FirstLineNo);
EdSetTextNo(W);
end;
EdBackupCurline(W);
UpdateScreen := True;
end; {EdGrowWindow}
procedure EdShrinkWindow(TopEdge : Boolean);
{-Reduce the size of the current window}
var
W : PwinDesc;
begin {EdShrinkWindow}
{Two or more windows previously guaranteed open}
{Check that window is large enough to shrink}
if (CurWin^.LastLineNo-CurWin^.FirstTextNo) < MinWindowLines then
Exit;
if TopEdge then begin
{Bottom Window}
{Subtract from top of window, adding it from previous window}
W := CurWin^.Backlink;
CurWin^.FirstLineNo := Succ(CurWin^.FirstLineNo);
W^.LastLineNo := Succ(W^.LastLineNo);
EdSetTextNo(CurWin);
end else begin
{Top or middle window}
{Subtract from bottom of window, adding it to next window}
W := CurWin^.FwdLink;
CurWin^.LastLineNo := Pred(CurWin^.LastLineNo);
W^.FirstLineNo := Pred(W^.FirstLineNo);
EdSetTextNo(W);
end;
EdBackupCurline(CurWin);
UpdateScreen := True;
end; {EdShrinkWindow}
function EdGetCommand(TopEdge : Boolean) : SizeCommands;
{-Get a window sizing command}
var
Ch : Char;
begin {EdGetCommand}
EdGetCommand := None;
Ch := EdGetAnyChar;
if Ch = Null then begin
{Extended character, get the other half}
Ch := EdGetAnyChar;
case Ch of
#72 : {Up arrow}
if TopEdge then
EdGetCommand := Bigger
else
EdGetCommand := Smaller;
#80 : {Down arrow}
if TopEdge then
EdGetCommand := Smaller
else
EdGetCommand := Bigger;
end;
end else if (Ch = ^M) or (Ch = ^[) then
EdGetCommand := Accept;
end; {EdGetCommand}
begin {EdSizeWindow}
{Make sure there are two windows or more}
if (WindowCount <= 1) then begin
EdErrormsg(56);
Exit;
end;
{See whether top or bottom edge of window is changing}
TopEdge := (CurWin^.FwdLink = Window1);
{Put up a prompt}
EdWritePromptLine(EdGetMessage(355));
UpdateScreen := True;
{Loop until done}
Done := False;
repeat
if UpdateScreen then begin
{Force redraw of entire screen}
IntrFlag := NoInterr;
EdUpdateScreen;
end;
case EdGetCommand(TopEdge) of
Bigger :
EdGrowWindow(TopEdge);
Smaller :
EdShrinkWindow(TopEdge);
Accept :
Done := True;
end;
until Done;
UpdateScreen := True;
end; {EdSizeWindow}
end.