home *** CD-ROM | disk | FTP | other *** search
- { MSEDIT.PAS
- MS 4.0
- Copyright (c) 1985, 87 by Borland International, Inc. }
-
- {$I msdirect.inc}
-
- unit MsEdit;
- {-Basic text editing commands}
-
- interface
-
- uses
- Crt, {Basic video operations - standard unit}
- Dos, {DOS interface - standard unit}
- Errors, {Runtime error handler}
- MsVars, {Global types and declarations}
- MsScrn1, {Fast screen writing routines}
- MsString, {String primitives}
- MsPtrOp, {Primitive pointer operations}
- EscSeq, {Returns text string for extended scan codes}
- MsCmds, {Maps keystrokes to commands}
- Int24, {DOS critical error handler}
- Message, {Message system}
- MsUser, {User keyboard input, line editing and error reporting}
- MsMemOp, {Text buffer allocation and deallocation}
- MsBack, {Background processes}
- MsScrn2; {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 EdGotoPage(Pno : Integer);
- {-Go to specified page number, assumes pagination is on}
-
- procedure EdLeftWord;
- {-Move cursor to previous word}
-
- procedure EdRightWord;
- {-Advance cursor to next word}
-
- procedure EdDeleteRightWord;
- {-Process delete right word command}
-
- procedure EdRightJustify(P : PlineDesc; Lmargin, Rmargin : Integer);
- {-Insert spaces in line to make it fill rmargin}
-
- procedure EdProcesstext(Ch : Char; ImmediateUpdate : Boolean);
- {-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}
-
- {==========================================================================}
-
- 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;
- if AT then
- {Adjust current column number to match appearance of previous line}
- Colno := EdAdjustColno(Curline, Curline^.Fwdlink, Colno);
- 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;
- if AT then
- {Adjust current column number to match appearance of previous line}
- Colno := EdAdjustColno(Curline, Curline^.Backlink, Colno);
- 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;
- EdResetPageLine(Curwin);
- 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;
- Rezoom : Boolean;
-
- 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;
-
- Rezoom := Zoomed and (W <> Curwin);
- if Rezoom then
- {toggle zoom off}
- EdZoomWindow(False);
- Curwin := W;
- if Rezoom then
- {toggle zoom back on}
- EdZoomWindow(False);
-
- 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);
- if AT then
- {Adjust current column number to match appearance of previous line}
- Colno := EdAdjustColno(Curline, Curline^.Fwdlink, Colno);
- 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);
- if AT then
- {Adjust current column number to match appearance of previous line}
- Colno := EdAdjustColno(Curline, Curline^.Backlink, Colno);
- end else
- Dec(Lineno);
- Dec(FullScroll);
- end;
- end; {EdScrollDown}
-
- procedure EdUpPage;
- {-Process up page command}
- var
- PageSize, I : Integer;
- P : PlineDesc;
-
- begin {EdUpPage}
- with Curwin^ do begin
- PageSize := Succ(Lastlineno-Firsttextno);
- I := 1;
- P := Curline;
- 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;
- if AT then
- {Adjust current column number to match appearance of previous line}
- Colno := EdAdjustColno(Curline, P, Colno);
- end;
- end; {EdUpPage}
-
- procedure EdDownPage;
- {-Process down page command}
- var
- PageSize, I : Integer;
- P : PlineDesc;
-
- begin {EdDownPage}
- with Curwin^ do begin
- PageSize := Succ(Lastlineno-Firsttextno);
- I := 1;
- P := Curline;
- 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;
- if AT then
- {Adjust current column number to match appearance of previous line}
- Colno := EdAdjustColno(Curline, P, Colno);
- end;
- end; {EdDownPage}
-
- procedure EdGotoPage(Pno : Integer);
- {-Go to specified page number, assumes pagination is on}
-
- begin {EdGotoPage}
- with Curwin^ do begin
- if EdGetPageNum(Curline) >= Pno then
- {Scan backwards to top of specified page}
- while EdPtrNotNil(Curline^.Backlink) and (EdGetPageNum(Curline) >= Pno) do
- EdUpLine;
- {Scan forward to top of specified page}
- while EdPtrNotNil(Curline^.Fwdlink) and (EdGetPageNum(Curline) < Pno) do
- EdDownLine;
- Colno := 1;
- end;
- end; {EdGotoPage}
-
- 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;
-
- {Up to previous line if within left margin}
- if WW then
- if (Colno <= 1) and (Wmargin > 1) and (Txt^[Colno] = Blank) then
- EdBackOneLine;
-
- 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;
- if WW then
- while (Colno < Wmargin) and (Curline^.Txt^[Colno] = Blank) do
- {Advance to next non-space or to left margin}
- Inc(Colno);
-
- end;
- end;
- end; {EdRightWord}
-
- procedure EdDeleteRightWord;
- {-Delete word to right of cursor}
- type
- CharClass = (InBlank, InAlphas, InElse);
- var
- Startclass : CharClass;
-
- function EdClass : CharClass;
- var
- Ch : Char;
-
- begin {EdClass}
- with Curwin^ do
- Ch := Curline^.Txt^[Colno];
- if Ch = Blank then
- EdClass := InBlank
- else if Ch in Alphas then
- EdClass := InAlphas
- else
- EdClass := InElse;
- end; {EdClass}
-
- begin {EdDeleteRightWord}
-
- with Curwin^ do begin
- 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;
-
- {Reset pagination}
- EdResetPageLine(Curwin);
- end;
-
- {Force screen to be fully updated}
- Intrflag := NoInterr;
-
- end; {EdDeleteRightWord}
-
- procedure EdRightJustify(P : PlineDesc; Lmargin, Rmargin : Integer);
- {-Insert spaces in line to make it fill rmargin}
- var
- EffLen, Len, I, J, Lptr, Tptr, Emargin,
- Nspaces, Espaces, Ispaces, Delta, Next : Integer;
- Template : array[1..Maxlinelength] of Integer;
- Tline : TextLine;
-
- begin {EdRightjustify}
-
- Len := EdTextLength(P);
- {Correct for effect of font toggle characters}
- EffLen := EdComputeEffectiveColNo(True, P, Len);
- Emargin := Rmargin+Len-EffLen;
-
- {Check length, leave line unchanged if empty or too long}
- if (EffLen > 0) and (EffLen < Rmargin) then begin
-
- with P^ do begin
- Lptr := 1;
-
- {Pass on leading spaces and characters left of left margin without change}
- while (Txt^[Lptr] = Blank) or (PrintMap[Txt^[Lptr]] <> PrtNone) or (Lptr <= Lmargin) do begin
- Tline[Lptr] := Txt^[Lptr];
- Inc(Lptr);
- end;
- Tptr := Pred(Lptr);
-
- {Initialize the space template}
- Nspaces := 0;
- for I := Lptr to Len do
- if Txt^[I] = Blank then begin
- Inc(Nspaces);
- Template[Nspaces] := 1;
- end;
-
- if Nspaces > 0 then begin
-
- {Compute the actual spaces in each position of the template}
- Espaces := Emargin-Len;
-
- while (Espaces > 0) do begin
-
- {Number of template locations to increment}
- Delta := Nspaces div Espaces;
- if (Nspaces mod Espaces) > (Espaces shr 1) then
- Inc(Delta);
- if Delta = 0 then
- Delta := 1;
-
- {Number of spaces to increment each template location chosen}
- if Espaces > Nspaces then
- Ispaces := Espaces div Nspaces
- else
- Ispaces := 1;
-
- {First template position to increment}
- Next := Succ(Delta) shr 1;
-
- {Increment each selected space location}
- while (Next <= Nspaces) and (Espaces > 0) do begin
- Template[Next] := Template[Next]+Ispaces;
- Next := Next+Delta;
- Espaces := Espaces-Ispaces;
- end;
-
- end; {While espaces>0}
- end; {If nspaces>0}
-
- {Write the justified line to the buffer}
- Nspaces := 0;
- for I := Lptr to Len do
- if Txt^[I] = Blank then begin
- Inc(Nspaces);
- {Fix up markers}
- EdFixBlockInsertedSpace(P, Succ(Tptr), Pred(Template[Nspaces]));
- EdFixMarkInsertedSpace(P, Succ(Tptr), Pred(Template[Nspaces]));
- {Insert the spaces}
- for J := 1 to Template[Nspaces] do begin
- Inc(Tptr);
- Tline[Tptr] := Blank;
- end;
- end else begin
- Inc(Tptr);
- Tline[Tptr] := Txt^[I];
- end;
-
- end; {with p^}
-
- {Copy output back to input}
- if not(EdSizeline(P, Tptr, False)) then
- Exit;
- Move(Tline[1], P^.Txt^[1], Tptr);
- FillChar(P^.Txt^[Succ(Tptr)], P^.Bufflen-Tptr, Blank);
-
- end; {Len>0 and len<=rmargin}
- end; {EdRightjustify}
-
- procedure EdProcesstext(Ch : Char; ImmediateUpdate : Boolean);
- {-Process text input}
- label
- ExitPoint;
- var
- Len, SaveCol, WrapCol : Integer;
-
- begin {EdProcesstext}
-
- with Curwin^ do begin
-
- if Colno >= Maxlinelength then
- {Cursor sitting at maximum length, ignore further characters}
- Exit;
-
- if WW and not(MarginRelease) then
- if (Colno < Wmargin) then begin
- {Cursor left of left margin, insert space to get to LM}
- if not(EdInsertSpace(Curline, Colno, Wmargin-Colno)) then
- Exit;
- Colno := Wmargin;
- end;
-
- 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;
-
- {Test for word wrap}
- if WW and not(MarginRelease) then
- if (Ch <> Blank) and (PrintMap[Ch] = PrtNone) then
- if (EdComputeEffectiveColNo(True, Curline, Colno) > Rmargin) then begin
-
- {Remove excess blanks, perhaps from prior justification}
- if CW then begin
- EdCompress(Curline, Wmargin, Colno, Len);
- if Colno > Len then
- Colno := Len;
- end;
-
- if Colno > Rmargin then begin
-
- SaveCol := Colno;
-
- {Back up to first blank within right margin}
- repeat
- Dec(Colno);
- until (Colno < 1) or
- ((EdComputeEffectiveColNo(True, Curline, Colno) <= Succ(Rmargin)) and
- (Txt^[Colno] = Blank));
-
- if (Colno = 0) or (EdComputeEffectiveColNo(True, Curline, Colno) < Wmargin) then begin
- {No blank found within margin}
- {Forward to first blank, if any}
- repeat
- Inc(Colno);
- until (Colno = SaveCol) or (Txt^[Colno] = Blank);
- if (Colno = SaveCol) or (EdComputeEffectiveColNo(True, Curline, Colno) <= Wmargin) then
- goto ExitPoint;
- end;
-
- {Move forward to next non-blank}
- while Txt^[Colno] = Blank do
- Inc(Colno);
-
- WrapCol := Colno;
-
- {Break the line}
- if Insertflag then
- EdNewLine
- else begin
- {Force insert mode}
- Insertflag := True;
- EdNewLine;
- Insertflag := False;
- end;
- {Might get memory overflow in EdNewLine}
- if Goterror then
- goto ExitPoint;
-
- {Justify wrapped line}
- if JU then
- EdRightJustify(Curline^.Backlink, Wmargin, Rmargin);
-
- {Move cursor after the text which was wrapped}
- Colno := Colno+SaveCol-WrapCol;
-
- end;
- end;
- end; {with Curline^}
-
- ExitPoint:
- Inc(Colno);
- Modified := True;
- EdResetPageLine(Curwin);
-
- {Get out fast if macro is in progress}
- if ImmediateUpdate and (EditUsercommandInput = 0) then begin
-
- {Assure that print control characters are updated on screen}
- if PrintMap[Ch] <> PrtNone then
- if AT then
- {Note that attribute changed within line}
- EdChangeFlag(Curline, True, NewAttr);
-
- {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}
- EdWritePromptLine(CtrlCharStr);
- {And assure ^U will get through}
- AbortEnable := False;
- EdProcesstext(EdGetAnyChar, True);
- 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}
- with Curwin^ do
- while EdPtrNotNil(Curline^.Fwdlink) do begin
- Inc(Clineno);
- EdFwdPtr(Curline);
- if Lineno > (Lastlineno-Firsttextno) then
- EdFwdPtr(TopLine)
- else
- Inc(Lineno);
- end;
- {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 := NewAttr;
- P^.Font := 0;
-
- {Insert the line into the current text stream}
-
- with Curwin^ do begin
-
- Modified := True;
- {Reset pagination}
- EdResetPageLine(Curwin);
-
- 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;
-
- {Restoring the line may have changed pagination}
- EdResetPageLine(Curwin);
-
- 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);
-
-
- end; {EdDelline}
-
- begin {EdDeleteLine}
- with Curwin^ do begin
- Modified := True;
- P := Curline;
-
- if EdPtrIsNil(P^.Fwdlink) then begin
-
- {This is the only line or 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;
-
- {Fixup any structures affected by deleting the line}
- EdDelline(P);
-
- {Put the line on undo stack if possible}
- if EdPtrNotNil(P^.Fwdlink) or (EdTextLength(P) > 0) then
- EdPushUndo(P);
-
- Colno := 1;
- EdResetPageLine(Curwin);
-
- 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}
-
- end.