program ef;
{ PASCAL-Entwurf fuer den TRAC Editor
  Version mit direkter Cursor Positionierung (d.h. ohne Eol-Tabelle) }

{$Ieddcl.pas}

{$Iedfct.pas}

{$Iedfnd.pas}

{$Iedclr.pas}

{$Ieddis.pas}

{$Iedscr.pas}

{$Iedcur.pas}

{$Iedpag.pas}

{$Iedalt.pas}

procedure show_status;
begin
GotoXY(1,1);
if insert_flag then write('I') else write('O');
write(' Index:',index:4);
write('  Char: ',hexbyte(ord(text[index])));
write('  Pos: ',cx:3,cy:3);
write('  Top: ',page_top_index:3,page_top_line:3,'  Bot: ',page_bottom_index:3,page_bottom_line:3);
write('  tlen: ',text_length:4,n_lines:4);
end; { show_status }

                           { --- Main program --- }

begin  { ef }

{$Iedini.pas}

text_length := 0;

{$Iedfil.pas}

text_length := text_length+1; text[text_length]:=CR;

n_lines:=0;
for i:=1 to text_length do
    if eol(i) then n_lines:=n_lines+1;
write('Text length = ',text_length, n_lines:6,' lines  -  Press RETURN...');
readln;

ClrScr;

first_page:
index:=1;
page_top_line:=1; find_page_bottom_line;
page_top_index:=1; find_page_bottom_index;
cx:=1; cy:=SCREENTOP; display_rest_page(index,cx,cy);

                       { Process input from keyboard }

finis:=false;
repeat
    show_status;
    GotoXY(cx,cy);
    read(KBD,ch);

switch:
    case ch of

{ Cursor positioning }

    ^H,
    ^S:  cursor_left;
    ^D:  cursor_right;
    ^E:  cursor_up;
    ^X:  cursor_down;
    ^Z:  page_up;
    ^W:  page_down;
    ^R:  prev_page;
    ^C:  next_page;

{ Text insertion/overwrite }

    ^N:  begin insert_char(CR); cursor_left; end;
  #$0D:  if insert_flag then insert_char(ch)
         else begin index:=index+td_eol(index); cursor_right; end;
  #$09,#$20..#$7E:
        if insert_flag then insert_char(ch)
        else begin if text[index]=CR then insert_char(ch)
                   else begin text[index]:=ch; display_char(index);
                              cursor_right; end;
            end;

{ Text deletion }

    ^G:  delete_chars(1);
  #$7F:  if index>1 then begin cursor_left; ch:=^G; goto switch; end;
    ^T:  begin
         i:=index;
         if text[i] in alphanums then
             while (i<text_length) and (text[i] in alphanums) do i:=i+1
         else
             while (i<text_length) and (text[i] in separators) do i:=i+1;
         delete_chars(i-index);
         end;
    ^Y:  begin index:=index-td_bol(index); delete_chars(td_eol(index)+1); end;

{ Editor status }

    ^V:  begin
         insert_flag:=not insert_flag;
         if insert_flag then write(cursor1) else write(cursor2);
         end;

{ Q-commands }

    ^Q:  begin
         read(KBD,ch);

{ Q-commands - Cursor positioning }

         if ch<>#$7F then ch:=chr(ord(ch) and $1F);
         case ch of
         ^S:  begin index:=index-td_bol(index); cx:=1; end;
         ^D:  begin index:=index+td_eol(index); cx:=cd_bol(index)+1; end;
         ^E:  begin
              find_index_above_cx(index,cx,cy-SCREENTOP); cy:=SCREENTOP;
              end;
         ^X:  begin
              i:=page_bottom_line-page_top_line+SCREENTOP-cy;
              find_index_below_cx(index,cx,i); cy:=cy+i;
              end;
         ^R:  goto first_page;
         ^C:  begin
              index:=text_length;
              i:=page_bottom_line-page_top_line;
              cx:=1; cy:=SCREENTOP+i;
              if n_lines-page_top_line >= PAGELEN then
                  begin
                  page_top_line:=max(1,n_lines-PAGELEN+1);
                  find_page_bottom_line;
                  page_top_index:=index;
                  find_index_above_cx(page_top_index,cx,i);
                  find_page_bottom_index;
                  display_rest_page(page_top_index,cx,SCREENTOP);
                  end;
              end;

{ Q-commands - Text deletion }

         ^Y:  delete_chars(td_eol(index));
       #$7F:  begin
              i:=td_bol(index); index:=index-i; delete_chars(i); cx:=1;
              end;

{         ^B:  if block_flag then
                  begin index:=block_begin; find_page(index); end;  <---
         ^K:  if block_flag then
                  begin index:=block_end+1; find_page(index); end }
         end;
         end;

{ K-commands }

    ^K:  begin
         read(KBD,ch); ch:=chr(ord(ch) and $1F);
         case ch of

{ K-commands - Block operations }

         ^H:  begin block_flag:=not block_flag; goto display_block; end;
         ^B:  begin
              block_begin:=index; block_flag:=(block_begin<=block_end);
              goto display_block;
              end;
         ^K:  begin
              block_end:=index-1; block_flag:=(block_begin<=block_end);
display_block:
              display_rest_page(page_top_index,1,SCREENTOP);
              end;
{
         ^C:  if block_flag then copy_block(true);
         ^V:  if block_flag then copy_block(false);
         ^Y:  begin
              if block_flag then
                  begin
                  k:=block_end-block_begin+1;
                  if k>0 then
                      begin
                      if index>=block_end then i:=index-k
                      else if index<block_begin then i:=index
                           else i:=block_begin;
                      index:=block_begin;
                      find_page(index);
                      delete_chars(k);
                      index:=i;
                      find_page(index);
                      block_flag:=false;
                      end;
                  end;
              end;
}
{ Finis }

         ^D:  begin finis:=true; index:=text_length; write(cursor2); end;
         end;
         end;

    end;
until finis;
GotoXY(1,SCREENBOTTOM);
end.  { ef }
