home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / edit / wpeditor.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  621.2 KB  |  14,129 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --hconv
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4.  
  5.   --$$$+ HCONV
  6.  
  7.   --
  8.   --
  9.   --        Written By Robert S. Cymbalski
  10.   --                   Science Applications International Corporation
  11.   --                   Energy Systems Group
  12.   --                   Ada Software Development Project Team
  13.   --                   2280 U.S. Highway 19 North, Suite 120
  14.   --                   Clearwater, Florida  33575
  15.   --
  16.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  17.   -- 
  18.       
  19.   with Text_IO            ;
  20.    
  21.   with Direct_IO          ;
  22.  
  23.   with string_library  ;
  24.   use  string_library  ;
  25.    
  26.   with basic_io_system ;
  27.   use  basic_io_system ;
  28.    
  29.   with crt_customization ;
  30.   use  crt_customization ;
  31.    
  32.   with crt_windows     ;
  33.   use  crt_windows     ;
  34.    
  35.   with Wordp_Globals   ;
  36.   use  Wordp_Globals   ;
  37.  
  38.   package help_convert is
  39.    
  40.     subtype data_file_name is ascii_text_file_name ;
  41.      
  42.     procedure DEFINE_HELP_FILE(SOURCE_FILE     : in ASCII_TEXT_FILE_NAME ;
  43.                                DESTINATION_FILE: in DATA_FILE_NAME );
  44.     -- This tool processes a help file in ASCII format to a format allowing
  45.     -- fast access to each of the various help screens.  It is for use by
  46.     -- the systems's manager to modify user help information to his 
  47.     -- particular audience.
  48.    
  49.   private
  50.    
  51.     block_size       : constant integer := 256 ; -- cannot be changed!
  52.     subtype block_index is integer range 0 .. block_size - 1 ;
  53.     type block_of_data is array ( block_index
  54.                                   range 0 .. block_size - 1 ) of character ;
  55.     type type_help_text_array is 
  56.            record
  57.              block_number : integer ;
  58.              data         : block_of_data ;
  59.            end record ;
  60.             
  61.     help_text_array : type_help_text_array ;
  62.      
  63.   end help_convert ;
  64.    
  65.   package body help_convert is
  66.    
  67.     package help_file_io is new direct_io ( type_help_text_array ) ;
  68.       -- unvalidated telesoft ada does not allow arrays, only records...
  69.  
  70.     procedure DEFINE_HELP_FILE(SOURCE_FILE     : in ASCII_TEXT_FILE_NAME ;
  71.                                DESTINATION_FILE: in DATA_FILE_NAME ) is
  72.     -- This tool processes a help file in ASCII format to a format allowing
  73.     -- fast access to each of the various help screens.  It is for use by
  74.     -- the systems's manager to modify user help information to his 
  75.     -- particular audience.
  76.    
  77.       maximum_help_topics       : constant integer := 40 ; 
  78.       subtype help_topic_index_number is INTEGER 
  79.                                            range 1 .. maximum_help_topics ;
  80.       subtype topic_name_type is string ( 1 .. 28 ) ;
  81.       blank_topic_name : constant topic_name_type 
  82.                                 := "                            " ;
  83.       type help_topic_description is 
  84.              record 
  85.                block_number   : INTEGER range 0 .. 32000 := 0 ;
  86.                place          : block_index              := 0 ;
  87.                help_code      : CHARACTER                := ascii.nul ;
  88.                topic_name     : topic_name_type          := blank_topic_name ;
  89.              end record ; 
  90.       type some_entries is array ( help_topic_index_number )
  91.                                             of help_topic_description ;
  92.       
  93.       help_description_array : some_entries ;
  94.       first_text_block_in_file             : constant integer := 6 ;
  95.    
  96.       next_character_position_within_block : INTEGER ; 
  97.       current_help_topic_number            : INTEGER ; 
  98.       Input_String_Length                  : INTEGER ;
  99.       Input_Line                           : pstring ;
  100.        
  101.       Put_Block_Error                      : EXCEPTION ;
  102.  
  103.       Help_Input_Text_File      : text_IO.FILE_TYPE ;
  104.       Help_Data_File            : help_file_io.FILE_TYPE ; 
  105.       Next_Output_Block         : help_file_io.POSITIVE_COUNT ;
  106.       master_window             : window_pointer ;
  107.       requested_source_file     : ascii_text_file_name ;
  108.       requested_destination_file: data_file_name ;
  109.        
  110.       procedure get_input_file_name is
  111.         ok : boolean ;
  112.       begin
  113.         if source_file = no_file then 
  114.           ok := false ;
  115.         else
  116.           ok_to_read( source_file , requested_source_file , ok ) ;
  117.         end if ;
  118.         if not ok then
  119.           -- we need to read in another file name 
  120.           -- here on no input file name or file does not exist.
  121.           if source_file /= no_file then
  122.             error( " File """ & string_library.compress(source_file)
  123.                                             & """ does not exist." ,
  124.                    not_fatal_error , operator_wait , short_beep ) ;
  125.           end if ;
  126.           loop
  127.             clear_end_of_screen( master_window ,  5 , 1 ) ;
  128.             goto_line_column   ( master_window ,  5 , 1 ) ;
  129.             crt_windows.put(
  130.                   "  Enter Help Input File Name ( or <return> to abort ) => ") ;
  131.             requested_source_file := 
  132.                             get_input_filename_or_return ;
  133.             if requested_source_file = no_file then
  134.               ok := true ;
  135.             elsif requested_source_file( 1 ) = ascii.esc then
  136.               -- an error, the file name did not exist
  137.               error(" File Name """ & compress(requested_source_file
  138.                        ( 2 .. requested_source_file'length ) )
  139.                                   & """ is invalid." ,
  140.                      not_fatal_error , operator_wait , short_beep ) ;
  141.             elsif not file_exists ( requested_source_file ) then
  142.               -- an error, the file name did not exist
  143.               error(" File """ & compress(requested_source_file
  144.                        ( 2 .. requested_source_file'length ) )
  145.                                   & """ does not exist." ,
  146.                      not_fatal_error , operator_wait , short_beep ) ;
  147.             else
  148.               ok := true ; -- because it does not exist...
  149.             end if ;
  150.           -- need to set the default environment
  151.           exit when ok ;
  152.           end loop ;
  153.         end if ;
  154.       end get_input_file_name ;
  155.        
  156.       function get_yes_no return boolean is
  157.       begin -- get_yes_no
  158.         return char_or_abort( 'N' , 'Y' , 'N' ) = 'Y' ;
  159.       end get_yes_no ;
  160.        
  161.       procedure get_output_file_name is 
  162.         done : boolean ;
  163.       begin -- get_output_file_name
  164.         requested_destination_file := destination_file ;
  165.         loop 
  166.           if requested_destination_file( 1 ) = ascii.esc then
  167.             -- an error, the file name did not exist
  168.             error(" File """ & compress(requested_destination_file
  169.                      ( 2 .. requested_destination_file'length ) )
  170.                                 & """ is an invalid name." ,
  171.                    not_fatal_error , operator_wait , short_beep ) ;
  172.             done := false ;
  173.           elsif file_exists ( requested_destination_file ) then
  174.             -- we must confirm that they want to save it
  175.             crt_windows.put( ascii.cr ) ;
  176.             crt_windows.put( ascii.cr ) ;
  177.             crt_windows.put("  File """ & compress(requested_destination_file)
  178.                             & """ already exists.  ");
  179.             crt_windows.put( ascii.cr ) ;
  180.             crt_windows.put( ascii.cr ) ;
  181.             crt_windows.put("  Delete """ & compress( requested_destination_file ) 
  182.                                    & """ and continue (Y/N) ? ");
  183.             done := get_yes_no ; -- if they say "Y", then we will just leave.
  184.             -- when it comes time to writing, we will automatically rename
  185.             -- otherwise, if they say no, then re-ask the question for a
  186.             -- file name 
  187.           else
  188.             done := requested_destination_file /= no_file ;
  189.           end if ;
  190.         exit when done ;
  191.           -- here when we are not done... must get a new file name
  192.           clear_end_of_screen( master_window , 13 , 1 ) ;
  193.           goto_line_column   ( master_window , 13 , 1 ) ;
  194.           crt_windows.put(
  195.                  "  Enter Help Output File Name ( or <return> to abort ) => ") ;
  196.           requested_destination_file := 
  197.                           get_output_filename_or_return (".hlp");
  198.           if requested_destination_file = no_file then
  199.             requested_source_file := no_file ;
  200.             done := true ;
  201.           end if ;
  202.         -- need to set the default environment
  203.         exit when done ;
  204.         end loop ;
  205.       end get_output_file_name ;
  206.        
  207.       procedure open_for_write( file_handle : in out help_file_io.file_type ;
  208.                                 file_name   : in out data_file_name         ;
  209.                                 successfull : out boolean            ) is
  210.         -- Open the file setting the handle 
  211.       begin -- open_for_write
  212.         if help_file_io.is_open(file_handle) then
  213.           help_file_io.close(file_handle);
  214.         end if ;
  215.         help_file_io.create(file_handle,help_file_io.inout_file,
  216.                                       no_blanks(file_name));
  217.         successfull := true ;
  218.       exception 
  219.         when others                    => successfull := false ;
  220.       end open_for_write ;
  221.        
  222.       procedure initialize is
  223.         -- set up the files for help definition
  224.         ok : boolean ;
  225.         final_name                : ascii_text_file_name ;
  226.         had_old_file              : boolean ;
  227.       begin -- initialize 
  228.         master_window := create_window ( 1 , basic_io_system.total_crt_col ,
  229.                                          1 , basic_io_system.total_crt_line ,
  230.                                          true , 1 ) ;
  231.         -- Create a screen window
  232.         -- Make the window the entire screen, with a 1 line status area
  233.         -- at the top of the window
  234.         set_current_window ( master_window ) ;
  235.         clear_prompt( master_window ) ;
  236.         clear_window( master_window ) ;
  237.         get_input_file_name ;
  238.         if requested_source_file /= no_file then
  239.           get_output_file_name ;
  240.           if requested_destination_file /= no_file then
  241.             -- we can open the files...
  242.             open_for_read( Help_Input_Text_File , requested_source_file , ok ) ;
  243.             if not ok then
  244.               -- we have a fatal error....
  245.               error(" Program Error: No File """ 
  246.                           & compress(requested_source_file) & """." ,
  247.                    fatal_error , operator_wait , short_beep ) ;
  248.             else
  249.               -- we are ready to try to open for output...
  250.               open_for_write( Help_Data_File , requested_destination_file , ok);
  251.               if not ok then
  252.                 -- we have a fatal error....
  253.                 error(" Program Error: Out File """ 
  254.                             & compress(requested_destination_file) & """." ,
  255.                      fatal_error , operator_wait , short_beep ) ;
  256.               else
  257.                 -- ok, both files are opened...
  258.                 for blockn in 1 .. first_text_block_in_file loop
  259.                   help_file_io.write(Help_Data_File , help_text_array , 
  260.                                      help_file_io.positive_count(blockn));
  261.                   -- just puts those blocks in as place holders.
  262.                 end loop ;
  263.                  
  264.                 Next_Output_Block := help_file_io.positive_count(
  265.                                                     first_text_block_in_file ) ;
  266.                                  --  this is the block our data should go into
  267.                 next_character_position_within_block := 0 ;
  268.                                  --  this is the position our data goes into
  269.                 current_help_topic_number := 1 ;
  270.                                  --  This is the next key to fill
  271.               end if ;
  272.             end if ;
  273.           end if ;
  274.         end if ;
  275.       end initialize ;
  276.        
  277.       Procedure DELETE ( str : in out pstring ; start , len : in integer ) is
  278.         str_length : integer ;
  279.       begin
  280.         str_length := length ( str ) ;
  281.         if start + len <= str_length then
  282.           for i in start+len .. str_length loop
  283.             str.data(i-len) := str.data(i) ;
  284.           end loop ;
  285.           set_length( str , str_length - len ) ;
  286.         else
  287.           set_length( str , start - 1 ) ;
  288.         end if ;
  289.       end ;
  290.        
  291.       procedure GET_LINE       is        --  get the next input line in//
  292.         in_line : string ( 1 .. 255 ) ;
  293.       begin -- GET_LINE 
  294.         text_io.get_line ( Help_Input_Text_File , 
  295.                            in_line , Input_String_Length ) ;
  296.         Input_Line := string_to_pstring ( In_Line ( 1 .. Input_String_Length ));
  297.       end GET_LINE ; 
  298.        
  299.       procedure PUT_BLOCK      is 
  300.         --  We have filled a block, now we need to put it to the disk//
  301.       begin -- PUT_BLOCK      
  302.         help_text_array.block_number := integer(next_output_block) ;
  303.         help_file_io.write ( Help_Data_File , help_text_array , 
  304.                                               Next_Output_Block ) ;
  305.         Next_Output_Block := Next_Output_Block + 1 ; 
  306.         next_character_position_within_block := 0 ; 
  307.       exception
  308.         when others => raise Put_Block_Error ;
  309.       end PUT_BLOCK ; 
  310.        
  311.       procedure Move_Data_To_Help_Area is  --  move a line to the output block//
  312.         TMP            : INTEGER ; 
  313.       begin -- Move_Data_To_Help_Area 
  314.         --  we want to add the current Input_Line to help_text_array...
  315.         -- next_character_position_within_block is where the data should go.  Put a <cr><lf>
  316.         -- after any line which is not length(0).  Increment Next_Output_Block
  317.         -- if we overflow this block.//
  318.         if length( Input_Line ) = 0 then 
  319.           help_text_array.data( 
  320.           next_character_position_within_block ) := ascii.nul ;
  321.           next_character_position_within_block := 
  322.                       next_character_position_within_block + 1 ; 
  323.           if next_character_position_within_block = block_size then 
  324.             PUT_BLOCK ; 
  325.           end if ; 
  326.         else 
  327.           TMP := 1 ;                     --  this is the next character to move
  328.                                          -- over//
  329.           while ( TMP <= length ( Input_Line ) ) loop   --  move the line over//
  330.             help_text_array.data( next_character_position_within_block ) 
  331.                         := Input_Line.data( TMP ) ; 
  332.             TMP := TMP + 1 ; 
  333.             next_character_position_within_block := 
  334.                         next_character_position_within_block + 1 ; 
  335.             if next_character_position_within_block = block_size then 
  336.               PUT_BLOCK ; 
  337.             end if ; 
  338.           end loop ;                     --  Now, We Need the <cr><lf>//
  339.           help_text_array.data( next_character_position_within_block ) := 
  340.                       ascii.cr ;
  341.           next_character_position_within_block := 
  342.                       next_character_position_within_block + 1 ; 
  343.           if next_character_position_within_block = block_size then 
  344.             PUT_BLOCK ; 
  345.           end if ; 
  346.         end if ; 
  347.       end Move_Data_To_Help_Area ; 
  348.        
  349.       procedure SHOWNUM        (   B1             , P1             , B2  
  350.                                   , P2             : in   INTEGER ) is 
  351.         I1             , 
  352.         I2             : INTEGER ; 
  353.       begin -- SHOWNUM 
  354.         I1 := ( B1 * block_size ) + P1 ; 
  355.         I2 := ( B2 * block_size ) + P2 ; 
  356.         basic_io_system.put( I2 - I1 , 5 ) ;
  357.       end SHOWNUM ; 
  358.        
  359.       procedure DOWORK         is 
  360.         ind : integer ;
  361.       begin -- DOWORK 
  362.         GET_LINE ;                       --  get rid of the environment//
  363.         while ( length ( input_line ) < 5    )
  364.         or else ( Input_Line.data( 1 ) = '?' ) 
  365.         or else ( Input_Line.data( 1 ) = '-' )
  366.         loop 
  367.           GET_LINE ; 
  368.         end loop ; 
  369.         crt_windows.put ( ascii.cr ) ;
  370.         crt_windows.put ( ascii.cr ) ;
  371.         while Input_Line.data( 1 ) /= '*' loop
  372.                                          --  we work until we hit a * as the
  373.                                          -- first character//
  374.                                          --  fill in key information//
  375.           help_description_array( current_help_topic_number )
  376.                       .block_number := integer(Next_Output_Block) ; 
  377.           help_description_array( current_help_topic_number )
  378.                       .PLACE := next_character_position_within_block ; 
  379.           help_description_array( current_help_topic_number )
  380.                       .help_code := Input_Line.data( 1 ) ; 
  381.           delete ( Input_Line , 1 , 3 ) ; --  line was 'A) Auto Indent....
  382.                                           -- Now is    'Auto Indent...//
  383.           if length( input_line ) > topic_name_type'length then
  384.             crt_windows.put( "  Error... Index Line Too Long..." ) ; 
  385.             crt_windows.put( Input_Line ) ; 
  386.             crt_windows.put ( ascii.cr ) ;
  387.             while ( Length ( Input_Line ) > topic_name_type'length ) loop
  388.               DELETE ( Input_Line , topic_name_type'length + 1  , 1 ) ; 
  389.             end loop ; 
  390.           end if ; 
  391.           ind := 1 ;
  392.           while Length ( Input_Line ) < topic_name_type'length loop
  393.             Input_Line := Input_Line & " " ;
  394.           end loop ;
  395.           help_description_array( current_help_topic_number )
  396.                       .topic_name := Input_Line.data( 1 .. length(input_line)) ;
  397.                                        --  Show progress...//
  398.           basic_io_system.put( "  " ) ; 
  399.           basic_io_system.put( current_help_topic_number , 2 ) ; 
  400.           basic_io_system.put( "  " ) ; 
  401.           basic_io_system.put( help_description_array( current_help_topic_number )
  402.                                   .block_number , 3 ) ; 
  403.           basic_io_system.put( "  " ) ; 
  404.           basic_io_system.put( help_description_array( current_help_topic_number )
  405.                                   .PLACE , 3 ) ; 
  406.           basic_io_system.put( "  " ) ; 
  407.           basic_io_system.put( help_description_array( current_help_topic_number )
  408.                                   .help_code ) ; 
  409.           basic_io_system.put( "  """ ) ; 
  410.           basic_io_system.put( help_description_array( current_help_topic_number )
  411.                                   .topic_name ) ; 
  412.           basic_io_system.put( '"' ) ;
  413.                                         --  Now, do the lines of data//
  414.           GET_LINE ; 
  415.           while Input_Line.data( 1 ) /= '*' loop   --  process a line//
  416.             Move_Data_To_Help_Area ;                   --  get the next line//
  417.             GET_LINE ; 
  418.           end loop ;                     --  Put The End On//
  419.           set_length ( Input_Line , 0 ) ;
  420.           Move_Data_To_Help_Area ;                     --  Now, show final statistics//
  421.           SHOWNUM ( help_description_array( current_help_topic_number )
  422.                       .block_number , 
  423.                     help_description_array( current_help_topic_number )
  424.                       .PLACE        ,
  425.                     integer(Next_Output_Block) , 
  426.                     next_character_position_within_block ) ; 
  427.           crt_windows.put ( ascii.cr ) ;              --  Now, prepare for the next one...//
  428.           current_help_topic_number := current_help_topic_number + 1 ; 
  429.           if current_help_topic_number > maximum_help_topics then 
  430.             basic_io_system.put( " Error...To Many Keys.... " ) ; 
  431.             crt_windows.put ( ascii.cr ) ;
  432.           end if ; 
  433.           GET_LINE ;                     --  get in the next index line//
  434.         end loop ; 
  435.         put_block ;
  436.       end DOWORK ; 
  437.        
  438.       procedure FINISHUP       is 
  439.       type code_array_type is array ( 0 .. 
  440.                 ( ( first_text_block_in_file - 1 ) * block_size ) - 1 )      
  441.                         of character ;
  442.       code_array : code_array_type ;
  443.        
  444.         procedure convert_from_entry_to_text ( t : in help_topic_description;
  445.                                                ot_place : in integer ) is
  446.         begin
  447.           -- we must move t data over into code_array starting at ot_place 
  448.           code_array ( ot_place + 00 ) := character'val(t.block_number / 64 );
  449.           code_array ( ot_place + 01 ) := character'val( 
  450.                                           ( ( t.block_number mod 64 ) * 2 ) 
  451.                                           + ( t.place / 128 ) ); -- lowest bit 
  452.           code_array ( ot_place + 02 ) := character'val( t.place mod 128 ) ;
  453.           code_array ( ot_place + 03 ) := t.help_code                       ;
  454.           for posn in 1 .. 28 loop
  455.             code_array ( ot_place + 3 + posn ) := t.topic_name ( posn ) ;
  456.           end loop ;
  457.         end convert_from_entry_to_text ;
  458.          
  459.       begin -- FINISHUP 
  460.         for topic in 1 .. maximum_help_topics loop
  461.           -- we must convert it over 
  462.           convert_from_entry_to_text ( help_description_array( topic ) , 
  463.                                        (topic-1)*32 ) ;
  464.         end loop ;
  465.         for blockn in 1 .. first_text_block_in_file - 1 loop
  466.           for posn in 0 .. block_size - 1 loop
  467.             help_text_array.data(posn) := code_array ( (blockn-1) * block_size
  468.                                                         + posn );
  469.           end loop ;
  470.           next_output_block := help_file_io.positive_count( blockn ) ;
  471.           put_block ;
  472.         end loop ;
  473.         help_file_io.close ( Help_Data_File ) ;
  474.       end ;
  475.  
  476.       procedure err( s : string ) is
  477.         c : extended_character ;
  478.        
  479.       begin
  480.         crt_windows.put ( ascii.cr );
  481.         crt_windows.put ( ascii.cr );
  482.         text_io.put_line( "Exception: " & s ) ;
  483.         crt_windows.put ( ascii.cr );
  484.         crt_windows.put ( ascii.cr );
  485.         text_io.put     ( "  Type <space> to continue.... ");
  486.         c := basic_io_system.get_transparent ;
  487.       end err ;
  488.        
  489.       procedure pause is
  490.         c : extended_character ;
  491.       begin
  492.         crt_windows.put ( ascii.cr );
  493.         text_io.put     ( "  Type <space> to continue.... ");
  494.         c := basic_io_system.get_transparent ;
  495.       end pause ;
  496.        
  497.     begin -- define_help_file
  498.       initialize ;
  499.       if requested_destination_file /= no_file 
  500.       and then requested_source_file /= no_file then
  501.         -- ok, we have a source and destination
  502.         dowork ;
  503.         finishup ;
  504.         pause ;
  505.       end if ;
  506.     exception
  507.       when Put_Block_Error => error( "Encountered Put_Block Error " ,
  508.                                      fatal_error , operator_wait , short_beep );
  509.       -- when user_abort        => null ;
  510.       when constraint_error  => err("Constraint Error");
  511.       when numeric_error     => err("Numeric Error");
  512.       when program_error     => err("Program Error");
  513.       when storage_error     => err("Storage Error");
  514.       when tasking_error     => err("Tasking Error");
  515.       when others            => err("Unknown Error");
  516.     end define_help_file ;
  517.   
  518.   begin -- help_convert ;
  519.     null ; -- no initialization needed 
  520.     -- to use, do the following two lines...
  521.     -- define_help_file( no_file , no_file ) ;
  522.     -- crt.do_crt ( crt.program_termination ) ;
  523.   end help_convert ;
  524.    
  525.   --$$$- HCONV
  526.  
  527. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  528. --runh.TXT;compile]hconv
  529. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  530.  
  531.   --$$$+ runh
  532.  
  533.   with crt_customization ;
  534.   use  crt_customization ;
  535.    
  536.   with Wordp_Globals   ;
  537.   use  Wordp_Globals   ;
  538.  
  539.   with help_convert    ;
  540.   use  help_convert    ;
  541.   
  542.   Procedure RunH is
  543.   
  544.   begin -- RunH ;
  545.     define_help_file( no_file , no_file ) ;
  546.     crt.do_crt ( crt.program_termination ) ;
  547.   end RunH ;
  548.    
  549.   --$$$- runh
  550. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  551. --editglob
  552. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  553.  
  554.   --$$$+ EDITGLOB
  555.    
  556.   -- File 008
  557.   --
  558.   -- Editor Written By Robert S. Cymbalski
  559.   --                   Science Applications International Corporation
  560.   --                   Energy Systems Group
  561.   --                   Ada Software Development Project Team
  562.   --                   2280 U.S. Highway 19 North, Suite 120
  563.   --                   Clearwater, Florida  33575
  564.   --
  565.   -- Globals      Written 29 Nov 84 - RSCymbalski
  566.   --
  567.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  568.   -- 
  569.           
  570.   with text_io ;
  571.   use  text_io ;
  572.        
  573.   with string_library  ;
  574.   use  string_library  ;
  575.    
  576.   with basic_io_system   ;
  577.    
  578.   with crt_customization ;
  579.    
  580.   with crt_windows       ;
  581.    
  582.   with Wordp_Globals   ;
  583.   use  Wordp_Globals   ;
  584.  
  585.   package editor_globals is
  586.          
  587.     subtype an_editor_command is crt_customization.
  588.                                  editor_customization.crt_editor_command ;
  589.       
  590.     -- type crt_editor_command is ( up_command         , down_command        , 
  591.      
  592.     -- Now, we define the logical window sizing
  593.         
  594.     MAX_LINE_NUMBER   : constant INTEGER := INTEGER'LAST ;
  595.     MAX_COLUMN_NUMBER : constant INTEGER := 512 ;
  596.         
  597.     subtype LINE_NUMBER is INTEGER range 0 .. MAX_LINE_NUMBER ;
  598.     subtype COLUMN_POSITION is INTEGER range 0 .. MAX_COLUMN_NUMBER ;
  599.       -- 0 in either signifies no set position
  600.         
  601.     -- Now, information for buffer lines
  602.         
  603.     Max_leading_spaces        : constant integer := 254 ;
  604.          
  605.     subtype extended_character is basic_io_system.extended_character ;
  606.      
  607.     subtype type_text_length     is integer range 0 .. max_column_number ;
  608.     subtype type_leading_spaces  is integer range 0 .. max_leading_spaces ;
  609.     type data_array_type         is array ( type_text_length   
  610.                                     range 1 .. MAX_COLUMN_NUMBER ) 
  611.                                     of extended_character ;
  612.     type type_text_line       is 
  613.               record
  614.                 data             : data_array_type ;    
  615.                 leading_spaces   : type_leading_spaces ;
  616.                 data_length      : type_text_length ;
  617.               end record ;
  618.          
  619.     Max_line_length           : constant integer :=  255 ;
  620.                -- Actual max number of text characters on a line
  621.     subtype type_line_length  is integer range 0 .. max_line_length ;
  622.     Max_Bytes_In_Line         : constant integer := Max_Line_Length + 3 ;
  623.                -- A line in the buffer has max_line_length characters 
  624.                -- and three control characters
  625.     Screen_Size               : constant integer := 
  626.                           basic_io_system.max_screen_lines * max_bytes_in_line ;
  627. standard_open_area : constant integer := screen_size ;
  628.                -- A standard working open area should be equivalent to
  629.                -- a screen of data
  630.     Minimum_Open_Area         : constant integer := Max_Bytes_In_Line * 2 ;
  631.                -- Whenever we are working, we must have two lines of 
  632.                -- room around us.
  633.     max_buffer_size           : constant integer := Screen_Size * 3 +
  634.                                                     standard_open_area ;
  635.                -- The buffer must be able to handle a screen of data,
  636.                -- bracketed by a screen on each side, and with the
  637.                -- standard open area following ;
  638.      
  639.     subtype type_buffer_position      is integer range 0 .. max_buffer_size  ;
  640.          
  641.     type SCREEN_ATTRIBUTE_TYPE is ( NO_SCREEN_ATTRIBUTE , INVERSE_VIDEO ) ;
  642.     type SCREEN_POSITION is
  643.      record
  644.        LINE   : basic_io_system.a_screen_line_number   := 0 ;
  645.        COLUMN : basic_io_system.a_screen_column_number := 0 ;
  646.      end record ;
  647.           
  648.     type COPY_MODE is ( INSERT , OVERSTRIKE ) ;
  649.           
  650.     type real_editor_buffer ;  -- To be defined Later
  651.         
  652.     type an_editor_buffer is access real_editor_buffer ;
  653.     NO_BUFFER : Constant an_editor_buffer := null ;
  654.         
  655.     current_buffer     : an_editor_buffer:= no_buffer ;
  656.         
  657.     type cursor_position is 
  658.            record
  659.              buffer_position : type_buffer_position   := 0 ;
  660.              file_line_number: line_number            := 0 ;
  661.              line_start      : type_buffer_position   := 0 ;
  662.              column_offset   : column_position        := 0 ;
  663.            end record ;
  664.              
  665.     cursor_nowhere : constant cursor_position := ( 0 , 0 , 0 , 0 ) ;
  666.      
  667.     type TEXT_POSITION is
  668.       record
  669.         LINE : LINE_NUMBER := 0 ;
  670.         COLUMN : COLUMN_POSITION := 0 ;
  671.         SCREEN_ATTRIBUTE : SCREEN_ATTRIBUTE_TYPE := NO_SCREEN_ATTRIBUTE ;
  672.         WHICH_BUFFER : an_editor_buffer := no_buffer ;
  673.       end record ;
  674.            
  675.     NO_SET_LOCATION : TEXT_POSITION := ( 0 , 0 , NO_SCREEN_ATTRIBUTE ,
  676.                                         NO_BUFFER ) ;
  677.           
  678.     type TEXT_RANGE is
  679.       record
  680.         LO_POSITION ,
  681.         HI_POSITION : TEXT_POSITION ;
  682.         ATTRIBUTE   : SCREEN_ATTRIBUTE_TYPE := NO_SCREEN_ATTRIBUTE ;
  683.       end record ;
  684.           
  685.     type marker_item ;
  686.     type MARKER_pointer is access marker_item ;
  687.     type marker_item is 
  688.       record
  689.         DATA       : TEXT_POSITION ;
  690.         PRIOR_item ,
  691.         NEXT_item  : MARKER_pointer ;
  692.       end record ;
  693.     NO_MARKER : constant MARKER_pointer := null ;
  694.         
  695.     subtype status_line_type is pstring ;
  696.         
  697.     -- The following is used to generate statistics on the user's efficiency
  698.         
  699.     time_in : basic_io_system.timer ;
  700.     time_out: basic_io_system.timer ;
  701.     keystrokes : integer ;
  702.          
  703.     -- Now, a number of buffer items
  704.         
  705.     Max_Buffer_Number : constant Integer := 10 ;
  706.     subtype A_Buffer_Number is Integer range 0 .. Max_Buffer_Number ;
  707.      
  708.     buffer_list : array ( a_buffer_number range 1 .. max_buffer_number )
  709.                   of an_editor_buffer := ( 1 .. max_buffer_number
  710.                                                 => no_buffer ) ;
  711.                    
  712.     type each_position             is record
  713.                                         data : extended_character ;
  714.                                         attr : screen_attribute_type ;
  715.                                       end record ;
  716.                   
  717.     type T_BUFFER                  is array ( type_buffer_position
  718.                                               range 0 .. max_buffer_size
  719.                                             ) of each_position ;
  720.          
  721.     -- The following is the description of the text I/O items
  722.     subtype text_file_type            is text_io.file_type ;
  723.         
  724.     -- The following is the description of the block I/O items
  725.     -- BLOCK_SIZE                     : constant integer := 1024 ; 
  726.     BLOCK_SIZE                     : constant integer :=  512 ;
  727.                        -- The programmer must guarantee that 
  728.                        -- block_size is greater than max_bytes_in_line
  729.                        -- This is a requirement of return_forward and
  730.                        -- backward line, so that we cannot get confused
  731.     BLOCK_MINUS                    : constant integer := block_size - 1 ;
  732.     subtype block_offset           is integer range 0 .. block_minus ;
  733.     type BLOCK                     is array ( block_offset 
  734.                                               range 0 .. block_minus 
  735.                                             ) of each_position;
  736.       
  737.     blank_file_name : constant ascii_text_file_name := no_file ;
  738.                                           
  739.     max_markers : constant integer := 10 ; 
  740.     subtype marker_number is integer range 0 .. max_markers ;
  741.     subtype valid_marker_number is marker_number range 1 .. max_markers ;
  742.     subtype STR10          is string ( 1 .. 10 ) ;
  743.     blank_marker       : constant str10 := "          " ;
  744.     type markers_array_content is
  745.       record
  746.         name : str10 ;
  747.         location : marker_pointer := no_marker ;
  748.       end record ;
  749.     type  MARKERS_ARRAY is   
  750.           array ( valid_marker_number 
  751.                   range 1 .. max_markers ) of markers_array_content ;    
  752.       
  753.     type TABTYPES       is ( TNONE          , TNORMAL        , TNUMBER   ) ; 
  754.     type a_tab_line     is array ( column_position ) of TABTYPES ; 
  755.         
  756.     type HEADER         is 
  757.       record 
  758.         FILENAME       : ascii_text_file_name ;   -- the file name//
  759.         marker_count   : marker_number ; --The count of valid markers//
  760.         markers        : MARKERS_ARRAY ; 
  761.         AUTOINDENT     : BOOLEAN ;   --  Environment stuff follows//
  762.         break_char     : character ;
  763.         CHECKCASE      : BOOLEAN ; 
  764.         ENABLE_CMDS    : BOOLEAN ; 
  765.         FILLING        : BOOLEAN ; 
  766.         HYPHENATE      : BOOLEAN ; 
  767.         JUSTIFY        : BOOLEAN ; 
  768.         save_envirn    : BOOLEAN ; 
  769.         TOKDEF         : BOOLEAN ; 
  770.         wordprocess    : BOOLEAN ; 
  771.         LMARGIN        : column_position ;
  772.         RMARGIN        : column_position ; 
  773.         PARAMARGIN     : column_position ;
  774.         CREATED        : basic_io_system.timer ;
  775.         LAST_USED      : basic_io_system.timer ;
  776.         first_five     ,
  777.         last_five      : string ( 1 .. 5 ) ;
  778.         tabline      :   a_tab_line ;
  779.       end record ; 
  780.         
  781.     -- The following is the description of the text buffer
  782.         
  783.     type real_editor_buffer is
  784.            record
  785.              buffer_number            : a_buffer_number ;
  786.                                         -- This number is assigned when a 
  787.                                         -- new buffer is allocated.  
  788.              window                   : crt_windows.window_pointer ; 
  789.                                         -- which window to work
  790.              -- now, text buffer information 
  791.              e_buf                    : t_buffer ;
  792.                                         -- This is where the actual text of a 
  793.                                         -- buffer resides....
  794.              bufcount                 : type_buffer_position ;
  795.                                         --  Number of valid characters in the
  796.                                         -- E_buf 
  797.              fixed_cursor             : cursor_position := cursor_nowhere ; 
  798.              floating_cursor          : cursor_position := cursor_nowhere ;
  799.              moving_cursor            : cursor_position := cursor_nowhere ;
  800.              top_screen_cursor        : cursor_position := cursor_nowhere ;
  801.              next_screen_cursor       : cursor_position := cursor_nowhere ;
  802.                
  803.              INPUTFILE                : text_file_type ; 
  804.                                         --   where we read text from
  805.              still_reading_input_file : boolean ;
  806.              input_file_name          : ascii_text_file_name   ;
  807.              copy_file_name           : ascii_text_file_name   ;
  808.              output_file_name         : ascii_text_file_name   ;
  809.              -- TOPFILE               , 
  810.              -- BOTFILE               : BLOCKFILE ; -- storage areas for text
  811.              PRESTOPBLOCK             : INTEGER ; 
  812.              PRESBOTBLOCK             : INTEGER ; 
  813.              prior_buffer             ,
  814.              following_buffer         : an_editor_buffer ;
  815.                
  816.              PAGEZERO                 : HEADER ; 
  817.              NAME                     : STRING( 1 .. 10 ) ;
  818.              MODE                     : COPY_MODE ;
  819.              open_buffer_area         : boolean         ;
  820.              first_open_position      : type_buffer_position ;
  821.              last_open_position       : type_buffer_position ;
  822.                
  823.              last_marked_position     : marker_pointer := no_marker ;
  824.            end record ;
  825.                 
  826.     type topush         is ( thetop , thebot ) ;
  827.     
  828.     need_prompt : boolean ; -- do we need to put the main prompt up ?
  829.      
  830.     subtype a_repeat_factor is integer ;
  831.     infinity                 : constant a_repeat_factor:= a_repeat_factor'last ;
  832.     current_repeat_factor    : a_repeat_factor         := 0 ;
  833.     current_command          : an_editor_command       := 
  834.                         crt_customization.editor_customization.illegal_command ;
  835.      
  836.     --  Text Buffer Layout Description...
  837.     --  
  838.     --  The text buffer has a very special format.  If corrupted, it 
  839.     --  can become impossible for the editor to recover.  Therefore, 
  840.     --  text buffer manipulation should NOT be attempted by any routines
  841.     --  other than those currently sitting in the buffer package.  
  842.     --
  843.     --  The text buffer is an array ( 1 .. max_buffer_size ) which 
  844.     --  contains the following when initialized:
  845.     --
  846.     --    <255>                Buffer Start Flag
  847.     --    <0><0><0>            Line Length / No Leading Spaces / Line Length
  848.     --    <255>                Buffer End Flag
  849.     --
  850.     --  If a single space is added, the buffer changes to the following:
  851.     --
  852.     --    <255>                Buffer Start Flag
  853.     --    <0><1><0>            Line Length / 1 Leading Space / Line Length
  854.     --    <255>                Buffer End Flag
  855.     --
  856.     --  If a single character X is added, the buffer changes to the following:
  857.     --
  858.     --    <255>                Buffer Start Flag
  859.     --    <1><0>X<1>           Line Length / No Leading Spaces /X/ Line Length
  860.     --    <255>                Buffer End Flag
  861.     --
  862.     --  If the text lines "Line 1<cr>  Line 2<cr>    Line 3<cr> is inserted   
  863.     --  then the buffer will look as follows:
  864.     --
  865.     --    <255>                Buffer Start Flag
  866.     --    <6><0>Line 1<6>
  867.     --    <6><2>Line 2<6>
  868.     --    <6><4>Line 3<6>
  869.     --    <0><0><0>
  870.     --    <255>                Buffer End Flag
  871.     --
  872.     --
  873.     --  Note that the max line length of 254 is real, because the 255 code
  874.     --  is used to signify the beginning and end of the buffer.  
  875.     --  Also note that the line length does NOT include the leading 
  876.     --  spaces.
  877.          
  878.     --  The Text area can be pictured as follows
  879.     --
  880.     --  <Prior Editing Buffer>         Pointed to by prior_buffer_number
  881.     --  <Top File>                     Blocks of text saved on disk
  882.     --  <E_buf>                        Text which can be manipulated
  883.     --  <Bottom File>                  Blocks of text saved on disk
  884.     --  <Input File>                   Input Text not yet read
  885.     --  <Following Editing Buffer>     Pointed to by following_buffer_number
  886.     --
  887.          
  888.   end editor_globals ;
  889.      
  890.   package body editor_globals is
  891.       
  892.   begin
  893.     -- EDITGLOB by SAIC/Clearwater Editor Globals              22 Jan 85
  894.     --
  895.     null ;
  896.     basic_io_system.put("  Maximum bytes taken up by one line in buffer => ");
  897.     basic_io_system.put(max_bytes_in_line);
  898.     basic_io_system.put_line;
  899.     basic_io_system.put("  Maximum Screen Size                          => ");
  900.     basic_io_system.put(screen_size);
  901.     basic_io_system.put_line;
  902.     basic_io_system.put("  Standard Open Area when adding to buffer     => ");
  903.     basic_io_system.put(Standard_Open_Area);
  904.     basic_io_system.put_line;
  905.     basic_io_system.put("  Minimum Open Area When working               => ");
  906.     basic_io_system.put(Minimum_Open_Area);
  907.     basic_io_system.put_line;
  908.     basic_io_system.put("  Maximum Characters In Buffer                 => ");
  909.     basic_io_system.put(max_buffer_size);
  910.     basic_io_system.put_line;
  911.   end editor_globals ;
  912.  
  913.   --$$$- EDITGLOB
  914.  
  915. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  916. --ewindows
  917. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  918.  
  919.   --$$$+ EWINDOWS
  920.    
  921.   --
  922.   -- File 009
  923.   --
  924.   -- Editor Written By Robert S. Cymbalski
  925.   --                   Science Applications International Corporation
  926.   --                   Energy Systems Group
  927.   --                   Ada Software Development Project Team
  928.   --                   2280 U.S. Highway 19 North, Suite 120
  929.   --                   Clearwater, Florida  33575
  930.   --
  931.   -- Window Manager Routines Written 19 Dec 84 - Robert S. Cymbalski
  932.   -- 
  933.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  934.   -- 
  935.         
  936.   with text_io         ;
  937.     
  938.   with string_library  ;
  939.   use  string_library  ;
  940.    
  941.   with crt_windows     ;
  942.   use  crt_windows     ;
  943.    
  944.   with Wordp_Globals   ;
  945.   use  Wordp_Globals   ;
  946.  
  947.   with editor_globals  ;
  948.   use  editor_globals  ;
  949.     
  950.   package edit_windows is
  951.            
  952.     subtype window_line_number         is crt_windows.window_line_number  ;
  953.     subtype window_column_number       is crt_windows.window_column_number;
  954.       -- integer because we don't know the limits on columns over
  955.        
  956.     procedure clear_window ( which_buffer : in an_editor_buffer ) ;
  957.       -- Clear the entire window of all text 
  958.          
  959.     procedure clear_prompt ( which_buffer : in an_editor_buffer ) ;
  960.       -- Clear the prompt line(s) of a window
  961.        
  962.     procedure Clear_Line       ( which_buffer : in an_editor_buffer       ;
  963.                                  line         : in window_line_number   ) ;
  964.       -- Clear the Line Specified
  965.          
  966.     procedure Clear_End_Of_Line( which_buffer : in an_editor_buffer       ;
  967.                                  line         : in window_line_number   ;
  968.                                  column       : in window_column_number ) ;
  969.       -- Clear the Line Specified, from line,column to end of line
  970.          
  971.     procedure Clear_Prompt_End_Of_Line( which_buffer : in an_editor_buffer     ;
  972.                                         line         : in window_line_number   ;
  973.                                       column       : in window_column_number) ;
  974.       -- Clear the Prompt Line Specified, from line,column to end of line
  975.      
  976.     procedure Clear_End_Of_Screen( which_buffer : in an_editor_buffer     ;
  977.                                  line         : in window_line_number   ;
  978.                                  column       : in window_column_number ) ;
  979.       -- Clear from Line, Column to the end of the window
  980.          
  981.     procedure goto_line_column ( which_buffer : in an_editor_buffer ;
  982.                                  line         : in window_line_number ;
  983.                                  column       : in window_column_number ) ;
  984.       -- Move to the specified line and column within a window.  Note that
  985.       -- the first column and line are numbered #1.  A Window area is 
  986.       -- exclusive of any prompt area
  987.          
  988.     procedure goto_Prompt_line_column ( which_buffer : in an_editor_buffer ;
  989.                                  line         : in window_line_number ;
  990.                                  column       : in window_column_number ) ;
  991.       -- Move to the specified line and column within a window's Prompt
  992.       -- area.  Note that the first column and line are numbered #1.  
  993.          
  994.     procedure set_prompt ( which_buffer : in an_editor_buffer ;
  995.                            which_prompt_line : in integer     ;
  996.                            prompt_line  : in string           ) ;
  997.       -- Set the prompt line as specified 
  998.        
  999.     procedure set_prompt ( which_buffer : in an_editor_buffer ;
  1000.                            which_prompt_line : in integer     ;
  1001.                            prompt_line  : in pstring          ) ;
  1002.       -- Set the prompt line as specified 
  1003.          
  1004.     procedure save_prompt_temporarily ;
  1005.       -- save the prompt area because an error message will be written
  1006.      
  1007.     procedure restore_prompt_after_temporary_save ;
  1008.       -- and restore the prompt area after that error message 
  1009.        
  1010.     Function Lowest_Column_Number  ( which_buffer : in an_editor_buffer )
  1011.                                    return window_column_number ;
  1012.        -- Return the lowest column number available on the window
  1013.       
  1014.     Function Highest_Column_Number ( which_buffer : in an_editor_buffer )
  1015.                                    return window_column_number ;
  1016.        -- Return the highest column number available on the window
  1017.       
  1018.     Function Window_Height         ( which_buffer : in an_editor_buffer )
  1019.                                    return window_Line_number ;
  1020.        -- Return the number of text lines in this window
  1021.       
  1022.     procedure set_reverse ( do_reverse : boolean ) ;
  1023.        -- set current_window.next_will_be_reverse and do the
  1024.        -- appropriate crt command
  1025.         
  1026.     procedure set_reverse_if_necessary ( do_reverse : boolean ) ;
  1027.        -- set current_window.next_will_be_reverse and do the
  1028.        -- appropriate crt command only if we are not set correctly
  1029.         
  1030.     function current_reverse return boolean ;
  1031.        -- return the current setting of the reverse flag 
  1032.         
  1033.     procedure put( c : character ) ;
  1034.       -- puts a character into the current window.  We only recognize
  1035.       -- ' ' .. tilde and ascii.cr.  Ascii.cr moves to the first column
  1036.       -- of the next line
  1037.        
  1038.     procedure put( s : string ) ;
  1039.       -- puts out a string of all printable characters
  1040.        
  1041.     procedure put( s : pstring ) ;
  1042.       -- puts out a pstring of all printable characters
  1043.        
  1044.     procedure put( num : integer ; len : integer ) ;
  1045.       -- put out the number within the len indicated
  1046.        
  1047.     procedure put( char_posn : in each_position ) ;
  1048.       -- put out the character at this position, and set any attributes
  1049.       -- as required
  1050.        
  1051.     procedure put_line ;
  1052.       -- start a new line within the window 
  1053.      
  1054.     procedure put_line( s : string ) ;
  1055.       -- output the string and then start a new line in the window 
  1056.      
  1057.     procedure put_line( s : pstring ) ;
  1058.       -- output the string and then start a new line in the window 
  1059.      
  1060.  -- function current_position return text_position ;
  1061.       -- return the line/column/and buffer for the current position 
  1062.        
  1063.     Procedure SHIFT ( SHIFT_BUFFER : in out an_editor_buffer ;
  1064.                       SHIFT_AMOUNT : in INTEGER ) ;
  1065.       -- *** change which relative character position on the line will be
  1066.       --     displayed in column 1 on the screen.  Applies to any buffer 
  1067.       --     mapped to the window.
  1068.          
  1069.     procedure store_shift ;
  1070.       -- store the shift amount for later because the current screen needs
  1071.       -- a shift of zero
  1072.        
  1073.     procedure restore_shift ;
  1074.       -- restore the old shift amount ;
  1075.        
  1076.     Procedure MAP_WINDOW ( WINDOW_NAME : in WINDOW_POINTER ;
  1077.                            BUFFER_NAME : in out an_editor_buffer ) ;
  1078.       -- *** uses window_name as the viewing area for buffer_name, where
  1079.       --     the viewing area was previously defined with create_window
  1080.         
  1081.     Procedure REFRESH_SCREEN ;
  1082.       -- ***  redraw screen to represent the current editing context
  1083.       --      requests a mandatory redraw of every line of every window
  1084.       --      which is mapped to the screen
  1085.         
  1086.     Procedure UPDATE_WINDOW ( which_buffer  : in out an_editor_buffer ) ;
  1087.       -- *** update screen to reflect the current internal state of the 
  1088.       --     buffer which the window_to_update is associated with
  1089.         
  1090.     Procedure UNMAP_WINDOW ( which_buffer   : in out an_editor_buffer ) ;
  1091.        -- *** disassociate window_to_unmap from its buffer ; erase window from
  1092.        --     the screen but do not remove it from the available windows list
  1093.    
  1094.     function current_window return window_pointer ;
  1095.      
  1096.     function no_window return window_pointer ;
  1097.      
  1098.     procedure scroll_up_entire_window (
  1099.                         number_of_lines_to_scroll : window_line_number ) ;
  1100.      
  1101.     procedure scroll_down_entire_window (
  1102.                         number_of_lines_to_scroll : window_line_number ) ;
  1103.     
  1104.   end edit_windows ;
  1105.      
  1106.   package body edit_windows is
  1107.      
  1108.     old_shift_amount : integer := 0 ;
  1109.      
  1110.     procedure clear_window ( which_buffer : in an_editor_buffer ) is
  1111.       -- Clear the entire window of all text 
  1112.     begin -- clear_window
  1113.       clear_window( which_buffer.window ) ;
  1114.     end clear_window ;
  1115.          
  1116.     procedure clear_prompt ( which_buffer : in an_editor_buffer ) is
  1117.       -- Clear the prompt line(s) of a window
  1118.     begin -- clear_prompt
  1119.       if which_buffer.window = crt_windows.no_window then 
  1120.         error(" Program Error: Clear Prompt On Null Window " ,
  1121.                    fatal_error , operator_wait , short_beep ) ;
  1122.       end if;
  1123.       clear_prompt(which_buffer.window) ;
  1124.     end clear_prompt ;
  1125.        
  1126.     procedure Clear_Line       ( which_buffer : in an_editor_buffer       ;
  1127.                                  line         : in window_line_number   ) is
  1128.       -- Clear the Line Specified
  1129.     begin -- Clear_Line
  1130.       clear_line(which_buffer.window , line) ;
  1131.     end Clear_Line ;
  1132.          
  1133.     procedure Clear_End_Of_Line( which_buffer : in an_editor_buffer       ;
  1134.                                  line         : in window_line_number   ;
  1135.                                  column       : in window_column_number ) is
  1136.       -- Clear the Line Specified, from line,column to end of line
  1137.     begin -- Clear_End_Of_Line
  1138.       clear_end_of_line(which_buffer.window , line , column) ;
  1139.     end Clear_End_Of_Line ;
  1140.          
  1141.     procedure Clear_Prompt_End_Of_Line( which_buffer : in an_editor_buffer ;
  1142.                                  line         : in window_line_number   ;
  1143.                                  column       : in window_column_number ) is
  1144.       -- Clear the Prompt Line Specified, from line,column to end of line
  1145.     begin -- Clear_Prompt_End_Of_Line
  1146.       clear_prompt_end_of_line(which_buffer.window , line , column) ;
  1147.     end Clear_Prompt_End_Of_Line ;
  1148.          
  1149.     procedure Clear_End_Of_Screen( which_buffer : in an_editor_buffer     ;
  1150.                                  line         : in window_line_number   ;
  1151.                                  column       : in window_column_number ) is
  1152.       -- Clear from Line, Column to the end of the window
  1153.     begin -- Clear_End_Of_Screen
  1154.       clear_end_of_screen(which_buffer.window , line , column) ;
  1155.     end Clear_End_Of_Screen ;
  1156.          
  1157.     procedure goto_line_column ( which_buffer : in an_editor_buffer ;
  1158.                                  line         : in window_line_number ;
  1159.                                  column       : in window_column_number ) is
  1160.       -- Move to the specified line and column within a window.  Note that
  1161.       -- the first column and line are numbered #1.  A Window area is 
  1162.       -- exclusive of any prompt area
  1163.     begin -- GoTo_Line_Column
  1164.       goto_line_column(which_buffer.window , line , column) ;
  1165.     end GoTo_Line_Column ;
  1166.          
  1167.     procedure goto_Prompt_line_column ( which_buffer : in an_editor_buffer ;
  1168.                                  line         : in window_line_number ;
  1169.                                  column       : in window_column_number ) is
  1170.       -- Move to the specified line and column within a window's Prompt
  1171.       -- area.  Note that the first column and line are numbered #1.  
  1172.     begin -- goto_prompt_line_column
  1173.       goto_prompt_line_column( which_buffer.window , line , column ) ;
  1174.     end goto_prompt_line_column ;
  1175.          
  1176.     procedure set_prompt ( which_buffer : in an_editor_buffer ;
  1177.                            which_prompt_line : in integer     ;
  1178.                            prompt_line  : in string           ) is
  1179.       -- Set the prompt line as specified 
  1180.     begin -- Set_Prompt
  1181.       set_prompt(which_buffer.window , which_prompt_line , prompt_line) ;
  1182.     end Set_Prompt ;
  1183.        
  1184.     procedure set_prompt ( which_buffer : in an_editor_buffer ;
  1185.                            which_prompt_line : in integer     ;
  1186.                            prompt_line  : in pstring          ) is
  1187.       -- Set the prompt line as specified 
  1188.     begin -- Set_Prompt
  1189.       set_prompt(which_buffer.window , which_prompt_line , prompt_line) ;
  1190.     end Set_Prompt ;
  1191.          
  1192.     procedure save_prompt_temporarily is
  1193.       -- save the prompt area because an error message will be written
  1194.     begin -- save_prompt_temporarily
  1195.       crt_windows.save_prompt_temporarily ;
  1196.     end save_prompt_temporarily ;
  1197.      
  1198.     procedure restore_prompt_after_temporary_save is
  1199.       -- and restore the prompt area after that error message 
  1200.     begin -- restore_prompt_after_temporary_save
  1201.       crt_windows.restore_prompt_after_temporary_save ;
  1202.     end restore_prompt_after_temporary_save ;
  1203.      
  1204.     Function Lowest_Column_Number ( which_buffer : in an_editor_buffer )
  1205.                                    return window_column_number is
  1206.        -- Return the Lowest column number available on the window
  1207.     begin -- Lowest_column_number 
  1208.       return Lowest_column_number( which_buffer.window);
  1209.     end Lowest_column_number ;
  1210.       
  1211.     Function Highest_Column_Number ( which_buffer : in an_editor_buffer )
  1212.                                    return window_column_number is
  1213.        -- Return the highest column number available on the window
  1214.     begin -- highest_column_number 
  1215.       return highest_column_number( which_buffer.window);
  1216.     end highest_column_number ;
  1217.       
  1218.     Function Window_Height         ( which_buffer : in an_editor_buffer )
  1219.                                    return window_Line_number is
  1220.        -- Return the number of text lines in this window
  1221.     begin -- window_height
  1222.       return window_height(which_buffer.window);
  1223.     end window_height ;
  1224.       
  1225.     procedure set_reverse ( do_reverse : boolean ) is
  1226.        -- set current_window.next_will_be_reverse and do the
  1227.        -- appropriate crt command
  1228.     begin -- set_reverse 
  1229.       crt_windows.set_reverse( do_reverse ) ;
  1230.     end set_reverse ;
  1231.         
  1232.     procedure set_reverse_if_necessary ( do_reverse : boolean ) is
  1233.        -- set current_window.next_will_be_reverse and do the
  1234.        -- appropriate crt command only if we are not set correctly
  1235.     begin -- set_reverse_if_necessary
  1236.       crt_windows.set_reverse_if_necessary( do_reverse ) ;
  1237.     end set_reverse_if_necessary ;
  1238.         
  1239.     function current_reverse return boolean is
  1240.        -- return the current setting of the reverse flag 
  1241.     begin -- current_reverse
  1242.       return crt_windows.current_reverse ;
  1243.     end current_reverse ;
  1244.      
  1245.     procedure put( c : character ) is
  1246.       -- puts a character into the current window.  We only recognize
  1247.       -- ' ' .. tilde and ascii.cr.  Ascii.cr moves to the first column
  1248.       -- of the next line
  1249.     begin -- put
  1250.       crt_windows.put(c);
  1251.     end put ;
  1252.        
  1253.     procedure put( s : string ) is
  1254.       -- puts out a string of all printable characters
  1255.     begin -- put
  1256.       crt_windows.put(s);
  1257.     end put ;
  1258.        
  1259.     procedure put( s : pstring ) is
  1260.       -- puts out a pstring of all printable characters
  1261.     begin -- put
  1262.       crt_windows.put(s);
  1263.     end put ;
  1264.        
  1265.     procedure put( num : integer ; len : integer ) is
  1266.       -- put out the number within the len indicated
  1267.     begin -- put 
  1268.       crt_windows.put(num,len);
  1269.     end put ;
  1270.        
  1271.     procedure put( char_posn : in each_position ) is
  1272.       -- put out the character at this position, and set any attributes
  1273.       -- as required
  1274.     begin -- put
  1275.       crt_windows.set_reverse_if_necessary( char_posn.attr = inverse_video ) ;
  1276.       crt_windows.put( character'val( char_posn.data ) ) ;
  1277.     end put ;
  1278.      
  1279.     procedure put_line is
  1280.       -- start a new line within the window 
  1281.     begin -- put_line
  1282.       crt_windows.put(ascii.cr);
  1283.     end put_line ;
  1284.      
  1285.     procedure put_line( s : string ) is
  1286.       -- output the string and then start a new line in the window 
  1287.     begin -- put_line
  1288.       crt_windows.put(s);
  1289.       crt_windows.put(ascii.cr);
  1290.     end put_line ;
  1291.     
  1292.     procedure put_line( s : pstring ) is
  1293.       -- output the string and then start a new line in the window 
  1294.     begin -- put_line
  1295.       crt_windows.put(s);
  1296.       crt_windows.put(ascii.cr);
  1297.     end put_line ;
  1298.     
  1299.  -- function current_position return text_position is
  1300.    -- line : crt_windows.window_line_number ;
  1301.    -- col  : crt_windows.window_column_number ;
  1302.  -- begin -- current_position 
  1303.    -- line := crt_windows.current_line ;
  1304.    -- col  := crt_windows.current_col  ;
  1305.    -- return text_position'( line , col , no_screen_attribute , current_buffer);
  1306.  -- end current_position ;
  1307.      
  1308.     Procedure SHIFT ( SHIFT_BUFFER : in out an_editor_buffer ;
  1309.                       SHIFT_AMOUNT : in INTEGER ) is
  1310.       -- *** change which relative character position on the line will be
  1311.       --     displayed in column 1 on the screen.  Applies to any buffer 
  1312.       --     mapped to the window.
  1313.       -- we do not let a call to this routine set a positive shift amount
  1314.       old_shift : integer ;
  1315.     begin -- shift
  1316.       old_shift := crt_windows.current_shift ;
  1317.       if old_shift + shift_amount > 0 then
  1318.         crt_windows.shift( shift_buffer.window , -old_shift ) ;
  1319.       else
  1320.         crt_windows.shift( shift_buffer.window , shift_amount ) ;
  1321.       end if ;
  1322.     end shift ; 
  1323.          
  1324.     procedure store_shift is
  1325.       -- store the shift amount for later because the current screen needs
  1326.       -- a shift of zero
  1327.     begin -- store_shift
  1328.       old_shift_amount := crt_windows.current_shift ;
  1329.       crt_windows.shift( current_buffer.window , - old_shift_amount ) ;
  1330.     end store_shift ;
  1331.      
  1332.     procedure restore_shift is
  1333.       -- restore the old shift amount ;
  1334.     begin --restore_shift
  1335.       crt_windows.shift( current_buffer.window ,
  1336.                      old_shift_amount - crt_windows.current_shift );
  1337.     end restore_shift ;
  1338.      
  1339.     Procedure MAP_WINDOW ( WINDOW_NAME : in WINDOW_POINTER ;
  1340.                            BUFFER_NAME : in out an_editor_buffer ) is
  1341.       -- *** uses window_name as the viewing area for buffer_name, where
  1342.       --     the viewing area was previously defined with create_window
  1343.     begin -- map_window 
  1344.       buffer_name.window := window_name ;
  1345.       current_buffer     := buffer_name ;
  1346.       set_current_window ( window_name ) ;
  1347.     end map_window ;
  1348.     
  1349.     Procedure REFRESH_SCREEN is
  1350.       -- ***  redraw screen to represent the current editing context
  1351.       --      requests a mandatory redraw of every line of every window
  1352.       --      which is mapped to the screen
  1353.     begin -- refresh_screen 
  1354.       for buf in 1 .. max_buffer_number loop
  1355.         if buffer_list( buf ) /= null then
  1356.           redisplay( buffer_list ( buf ) . window ) ;
  1357.         end if ;
  1358.       end loop ;
  1359.     end refresh_screen ;
  1360.         
  1361.     Procedure UPDATE_WINDOW ( which_buffer  : in out an_editor_buffer ) is
  1362.       -- *** update screen to reflect the current internal state of the 
  1363.       --     buffer which the window_to_update is associated with
  1364.     begin -- update_window 
  1365.       redisplay( which_buffer.window ) ;
  1366.     end update_window ;
  1367.         
  1368.     Procedure UNMAP_WINDOW ( which_buffer   : in out an_editor_buffer ) is
  1369.        -- *** disassociate window_to_unmap from its buffer ; erase window from
  1370.        --     the screen but do not remove it from the available windows list
  1371.     begin -- unmap_window
  1372.       -- window_to_unmap.buffer := null ;
  1373.       -- if window_to_unmap = which_window then 
  1374.       --   which_window := next_most_recent_which_window ;
  1375.       --   current_buffer := which_window.buffer ;
  1376.       --   cursor.buffer.line := which_window.current_row ;
  1377.       --   cursor.buffer.column := which_window.current_column ;
  1378.       -- end if ;
  1379.       -- remove window_to_unmap from the screen area
  1380.       -- return screen area to adjacent windows if original_length of adjacent
  1381.       -- windows warrants it
  1382.       if crt_windows.current_window = which_buffer.window then
  1383.         set_current_window( crt_windows.no_window ) ;
  1384.       end if ;
  1385.       dispose_window( which_buffer.window ) ;
  1386.     end unmap_window ;
  1387.    
  1388.     function current_window return window_pointer is
  1389.     begin -- current_window
  1390.       return crt_windows.current_window ;
  1391.     end current_window ;
  1392.      
  1393.     function no_window return window_pointer is
  1394.     begin -- no_window
  1395.       return crt_windows.no_window ;
  1396.     end no_window ;
  1397.      
  1398.     procedure scroll_up_entire_window (
  1399.                         number_of_lines_to_scroll : window_line_number ) is
  1400.     begin -- scroll_up_entire_window 
  1401.       crt_windows.scroll_up_entire_window( number_of_lines_to_scroll ) ;
  1402.     end scroll_up_entire_window ;
  1403.      
  1404.     procedure scroll_down_entire_window (
  1405.                         number_of_lines_to_scroll : window_line_number ) is
  1406.     begin -- scroll_down_entire_window 
  1407.       crt_windows.scroll_down_entire_window( number_of_lines_to_scroll ) ;
  1408.     end scroll_down_entire_window ;
  1409.     
  1410.   begin -- Edit_Windows
  1411.     -- EWINDOWS by SAIC/Clearwater Editor Window Management    22 Jan 85
  1412.     null ;
  1413.   end edit_windows ;
  1414.  
  1415.   --$$$- EWINDOWS
  1416.  
  1417. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1418. --markers
  1419. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1420.  
  1421. --$$$+ MARKERS
  1422.    
  1423.   --
  1424.   -- File 011
  1425.   --
  1426.   -- Editor Written By Robert S. Cymbalski
  1427.   --                   Science Applications International Corporation
  1428.   --                   Energy Systems Group
  1429.   --                   Ada Software Development Project Team
  1430.   --                   2280 U.S. Highway 19 North, Suite 120
  1431.   --                   Clearwater, Florida  33575
  1432.   --
  1433.   -- Marker Packages        Written 26 Dec 84 - RSC
  1434.   --
  1435.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  1436.   -- 
  1437.        
  1438.   with string_library  ;
  1439.   use  string_library  ;
  1440.    
  1441.   with crt_customization ;
  1442.   use  crt_customization ;
  1443.    
  1444.   with editor_globals ;
  1445.   use  editor_globals ;
  1446.     
  1447.   with edit_windows ;
  1448.   use  edit_windows ;
  1449.    
  1450.   package markers is
  1451.     
  1452.   PACKAGE TEXT_POSITION_HANDLER is
  1453.        
  1454.   --
  1455.   -- Text Position Handler Written 12 Nov 84 - RSC
  1456.   --                       revised 18 Dec 84 - RSC
  1457.   --
  1458.       
  1459.     Function "<" ( LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN ;
  1460.       -- is left position before the right position
  1461.         
  1462.     Function ">" ( LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN ;
  1463.       -- is left position after the right position 
  1464.          
  1465.     Function LT  ( LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN ;
  1466.       -- is left position before the right position
  1467.         
  1468.     Function GT  ( LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN ;
  1469.       -- is left position after the right position 
  1470.          
  1471.     Procedure NORMALIZE_RANGE ( A_RANGE : in out TEXT_RANGE ) ;
  1472.       -- make sure that the lo range is less than the 
  1473.      -- high range
  1474.         
  1475.   end ;
  1476.     
  1477.   PACKAGE TEXT_POS_DOUBLE_LINKED_LIST is
  1478.        
  1479.   --
  1480.   -- Text Position List Handler Written 12 Nov 84 - RSC
  1481.   --                            revised 03 Dec 84 - RSC
  1482.   --
  1483.       
  1484.     Function ALLOCATE_LIST_ITEM( WITH_NEW_VALUE : in TEXT_POSITION )
  1485.                                return marker_pointer ;
  1486.       -- allocate a new item & set its data value to with_new_value
  1487.          
  1488.     Procedure DE_ALLOCATE_LIST_ITEM ( OLD_ITEM : in out marker_pointer ) ;
  1489.       -- de-allocate the old list item
  1490.          
  1491.     Function FIRST_IN_LIST return marker_pointer ;
  1492.       -- return the first item in the list
  1493.         
  1494.     Function LAST_IN_LIST  return marker_pointer ;
  1495.       -- return the last item in the list
  1496.         
  1497.     Function NEXT_IN_LIST ( OLD_ITEM : in marker_pointer ) 
  1498.                          return marker_pointer ;
  1499.       -- return next item from list
  1500.          
  1501.     Function PRIOR_IN_LIST ( OLD_ITEM : in marker_pointer )
  1502.                           return marker_pointer ;
  1503.       -- return prior item from list
  1504.                              
  1505.   end ;
  1506.         
  1507.   PACKAGE MARKER_MANAGER is
  1508.     
  1509.   --
  1510.   -- Marker Manager Written 12 Nov 84 - RSC
  1511.   --                revised 05 Dec 84 - RSC
  1512.   --
  1513.     
  1514.     -- use text_pos_double_linked_list ;
  1515.       
  1516.     --  this allocates space for markers & manages them
  1517.         
  1518.     -- don't allow any operations on markers except
  1519.     -- "=" & "=/".
  1520.     
  1521.     -- you can't do anything with a marker except
  1522.     --   1) set it
  1523.     --   2) check it's position
  1524.     --   3) kill it
  1525.     --   4) see if it specifies the same position as another
  1526.     --      marker ( line = line ; column = column )
  1527.     -- you can not assign it or anything ...
  1528.       
  1529.     Procedure  NEW_MARKER  ( A_NEW_MARKER : out marker_pointer ) ;
  1530.          -- allocate a new marker
  1531.          
  1532.     Procedure DISPOSE ( OLD_MARKER : in out marker_pointer ) ;
  1533.          -- de-allocate an old marker
  1534.             
  1535.     Procedure LOAD_MARKER ( MARKER_NAME  : in out marker_pointer ;
  1536.                             WITH_ADDRESS : in TEXT_POSITION ) ;
  1537.          -- set the value of that marker with the specified position
  1538.             
  1539.     Function MARKERS_POSITION ( THE_MARKER : in marker_pointer )
  1540.                                 return TEXT_POSITION ;
  1541.          -- returns specified position of the given marker
  1542.                                  
  1543.     Procedure MARK ( A_MARKER       : in out marker_pointer ;
  1544.                      WITH_ATTRIBUTE : in SCREEN_ATTRIBUTE_TYPE ) ;
  1545.          -- set the marker to have the specified attribute.
  1546.             
  1547.     Procedure UPDATE_MARKERS_FOR_ADDED_TEXT 
  1548.                             ( This_Buffer : in an_editor_buffer ;
  1549.                             NEW_TEXT_RANGE : in out TEXT_RANGE ) ;
  1550.          -- update all marker positions because text was
  1551.          -- added between the range
  1552.             
  1553.     Procedure UPDATE_MARKERS_FOR_DELETED_TEXT
  1554.                             ( This_Buffer : in an_editor_buffer ;
  1555.                             OLD_TEXT_RANGE : in out TEXT_RANGE ) ;
  1556.         -- update all markers because the old text 
  1557.         -- range was deleted
  1558.         
  1559.     Procedure CLEAR_MARKERS ( FROM_BUFFER : in an_editor_buffer ) ;
  1560.         -- Clear all markers which are in that buffer 
  1561.      
  1562.   end ;
  1563.           
  1564.   end markers ;
  1565.     
  1566.   package body markers is 
  1567.     
  1568.   PACKAGE body TEXT_POSITION_HANDLER is
  1569.        
  1570.     -- text position definitions
  1571.          
  1572.     Function "<" ( LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN is
  1573.       -- is left position before the right position
  1574.         
  1575.     begin
  1576.       -- Does not check to see if in same buffer 
  1577.       if ( LEFT.LINE < RIGHT.LINE ) then
  1578.         return TRUE ;
  1579.       elsif ( LEFT.LINE > RIGHT.LINE ) then
  1580.         return FALSE ;
  1581.       else
  1582.         return ( LEFT.COLUMN < RIGHT.COLUMN ) ;
  1583.       end if ;
  1584.     end ;
  1585.         
  1586.     Function ">" (LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN is
  1587.       -- is left position before the right position
  1588.     begin
  1589.       -- Does not check to see if in same buffer 
  1590.       return RIGHT < LEFT ;
  1591.     end ;
  1592.         
  1593.     Function LT  ( LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN is
  1594.       -- is left position before the right position
  1595.         
  1596.     begin
  1597.       -- Does not check to see if in same buffer 
  1598.       if ( LEFT.LINE < RIGHT.LINE ) then
  1599.         return TRUE ;
  1600.       elsif ( LEFT.LINE > RIGHT.LINE ) then
  1601.         return FALSE ;
  1602.       else
  1603.         return ( LEFT.COLUMN < RIGHT.COLUMN ) ;
  1604.       end if ;
  1605.     end ;
  1606.         
  1607.     Function GT  (LEFT , RIGHT : TEXT_POSITION ) return BOOLEAN is
  1608.       -- is left position before the right position
  1609.     begin
  1610.       -- Does not check to see if in same buffer 
  1611.       return RIGHT < LEFT ;
  1612.     end ;
  1613.         
  1614.     Procedure NORMALIZE_RANGE ( A_RANGE : in out TEXT_RANGE ) is
  1615.       -- make sure that the low range is less than the
  1616.       -- high range
  1617.       TEMP_POSITION : TEXT_POSITION ;
  1618.     begin
  1619.       -- Does not check to see if in same buffer 
  1620.       if gt ( A_RANGE.LO_POSITION , A_RANGE.HI_POSITION ) then
  1621.         TEMP_POSITION := A_RANGE.LO_POSITION ;
  1622.         A_RANGE.LO_POSITION := A_RANGE.HI_POSITION ;
  1623.         A_RANGE.HI_POSITION := TEMP_POSITION ;
  1624.       end if ;
  1625.     end normalize_range ;
  1626.         
  1627.   Begin  -- TEXT_POSITION_HANDLER
  1628.     -- TEXTPOS  by SAIC/Clearwater Text Position Handler       21 Dec 84
  1629.     null ;
  1630.   End TEXT_POSITION_HANDLER ;
  1631.     
  1632.   use  TEXT_POSITION_HANDLER ;
  1633.         
  1634.   PACKAGE body TEXT_POS_DOUBLE_LINKED_LIST is
  1635.      
  1636.     ITEM_LIST_HEAD : marker_pointer := null ;
  1637.     ITEM_LIST_TAIL : marker_pointer := null ;
  1638.         
  1639.     Function ALLOCATE_LIST_ITEM ( WITH_NEW_VALUE : in TEXT_POSITION )
  1640.                                 return marker_pointer is
  1641.       -- allocate a new item & set its data value to with_new_value
  1642.       AN_ITEM : marker_pointer ;
  1643.     begin
  1644.       AN_ITEM := NEW marker_item ;
  1645.       AN_ITEM.DATA := WITH_NEW_VALUE ;
  1646.       AN_ITEM.PRIOR_ITEM := ITEM_LIST_TAIL ;
  1647.       AN_ITEM.NEXT_ITEM := null ;
  1648.       if item_list_tail = null then
  1649.         -- a new list
  1650.         item_list_head := an_item ;
  1651.         item_list_tail := an_item ;
  1652.       else
  1653.         -- an old list
  1654.         ITEM_LIST_TAIL.NEXT_ITEM := AN_ITEM ;
  1655.         ITEM_LIST_TAIL := AN_ITEM ;
  1656.       end if;
  1657.       return AN_ITEM ;
  1658.     end ;
  1659.         
  1660.     Procedure DE_ALLOCATE_LIST_ITEM ( OLD_ITEM : in out marker_pointer ) is
  1661.       -- de-alloate the old list item
  1662.     begin
  1663.       if OLD_ITEM = null then
  1664.         null ;  -- really an error ...
  1665.       else
  1666.         if OLD_ITEM = ITEM_LIST_HEAD then
  1667.           ITEM_LIST_HEAD := ITEM_LIST_HEAD.NEXT_ITEM ;
  1668.         end if ;
  1669.         if OLD_ITEM = ITEM_LIST_TAIL then
  1670.           ITEM_LIST_TAIL := ITEM_LIST_TAIL.PRIOR_ITEM ;
  1671.         end if ;
  1672.         -- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  1673.         -- *** release ( OLD_ITEM ) ;  ***
  1674.         -- $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  1675.         OLD_ITEM := null ;
  1676.       end if ;
  1677.     end ;
  1678.         
  1679.     Function FIRST_IN_LIST return marker_pointer is
  1680.       -- return first item in the list
  1681.     begin
  1682.       return ITEM_LIST_HEAD ;
  1683.     end ;
  1684.         
  1685.     Function LAST_IN_LIST return marker_pointer is
  1686.       -- return last item in the list
  1687.     begin
  1688.       return ITEM_LIST_TAIL ;
  1689.     end ;
  1690.         
  1691.     Function NEXT_IN_LIST ( OLD_ITEM : in marker_pointer ) 
  1692.                           return marker_pointer is
  1693.       -- return next item from list
  1694.     begin
  1695.       return OLD_ITEM.NEXT_ITEM ;
  1696.     end ;
  1697.         
  1698.     Function PRIOR_IN_LIST ( OLD_ITEM : in marker_pointer ) 
  1699.                            return marker_pointer is
  1700.       -- returns prior item from list
  1701.     begin
  1702.       return OLD_ITEM.PRIOR_ITEM ;
  1703.     end ;
  1704.         
  1705.   Begin  --  DOUBLE_LINKED_LIST_PACKAGE
  1706.     -- All done automatically 
  1707.     -- TEXTLIST by SAIC/Clearwater Text Position Linked List   18 Dec 84
  1708.     null ;
  1709.   end TEXT_POS_DOUBLE_LINKED_LIST ;
  1710.     
  1711.   use  TEXT_POS_DOUBLE_LINKED_LIST ;
  1712.    
  1713.   PACKAGE body MARKER_MANAGER is
  1714.         
  1715.     Procedure  NEW_MARKER  ( A_NEW_MARKER : out marker_pointer ) is
  1716.       -- allocate a new marker
  1717.     Begin
  1718.       A_NEW_MARKER := ALLOCATE_LIST_ITEM (  NO_SET_LOCATION ) ;
  1719.         -- allocate a new marker & set its text_position
  1720.         -- to no location set yet
  1721.     End ;
  1722.         
  1723.     Procedure DISPOSE ( OLD_MARKER : in out marker_pointer ) is
  1724.       -- get rid of old marker
  1725.     Begin
  1726.       DE_ALLOCATE_LIST_ITEM ( OLD_MARKER ) ;
  1727.     End ;
  1728.         
  1729.     Procedure LOAD_MARKER ( MARKER_NAME : in out marker_pointer ;
  1730.                            WITH_ADDRESS : in TEXT_POSITION ) is
  1731.       -- set marker value with the specified position
  1732.          
  1733.     Begin
  1734.       if marker_name /= NO_MARKER then
  1735.         NEW_MARKER  ( marker_name ) ;
  1736.       end if ;
  1737.       MARKER_NAME.DATA := WITH_ADDRESS ;
  1738.     End ;
  1739.         
  1740.     Function MARKERS_POSITION ( THE_MARKER : in marker_pointer ) 
  1741.             return TEXT_POSITION is
  1742.       -- returns specified position for given marker
  1743.         
  1744.     Begin
  1745.       return THE_MARKER.DATA ;
  1746.     End ;
  1747.         
  1748.     Procedure MARK ( A_MARKER       : in out marker_pointer ;
  1749.                     WITH_ATTRIBUTE : in SCREEN_ATTRIBUTE_TYPE ) is
  1750.          -- set the marker to have the specified attribute.
  1751.          -- *** also change attribute if necessary !!! ***
  1752.     Begin
  1753.       if A_MARKER /= NO_MARKER then
  1754.         NEW_MARKER  ( A_MARKER ) ;
  1755.       end if ;
  1756.       LOAD_MARKER( A_MARKER, text_position'( 
  1757.                                  current_buffer.fixed_cursor.file_line_number ,
  1758.                                  current_buffer.fixed_cursor.column_offset    ,
  1759.                                  with_attribute ,
  1760.                                  current_buffer) ) ;
  1761.     End ;
  1762.         
  1763.     Procedure UPDATE_MARKERS_FOR_ADDED_TEXT 
  1764.                             ( This_Buffer : in an_editor_buffer ;
  1765.                             NEW_TEXT_RANGE : in out TEXT_RANGE ) is
  1766.       -- update all marker positions because text was
  1767.       -- added between the range
  1768.       A_MARKER : marker_pointer ;
  1769.     Begin
  1770.       A_MARKER := FIRST_IN_LIST ;
  1771.       WHILE A_MARKER /= null loop
  1772.         if a_marker.data.which_buffer = this_buffer then
  1773.           -- OK , we match the current buffer and can work.
  1774.           if gt ( NEW_TEXT_RANGE.LO_POSITION , A_MARKER.DATA ) then
  1775.             null ;  -- marker not affected - marker before the added range
  1776.           else
  1777.             -- this marker is affected
  1778.             if A_MARKER.DATA.LINE = NEW_TEXT_RANGE.LO_POSITION.LINE then
  1779.               -- then text added to this line before this position,
  1780.               -- so the column is affected
  1781.                A_MARKER.DATA.COLUMN := A_MARKER.DATA.COLUMN -
  1782.                                       NEW_TEXT_RANGE.LO_POSITION.COLUMN +
  1783.                                       NEW_TEXT_RANGE.HI_POSITION.COLUMN ;
  1784.             else
  1785.               null ;  -- column is not affected
  1786.             end if ;
  1787.             -- obtain new line number for the marker
  1788.             A_MARKER.DATA.LINE := A_MARKER.DATA.LINE -
  1789.                                   NEW_TEXT_RANGE.LO_POSITION.LINE +
  1790.                                   NEW_TEXT_RANGE.HI_POSITION.LINE ;
  1791.           end if ;
  1792.         end if ;
  1793.         -- get next marker to check
  1794.         A_MARKER := NEXT_IN_LIST ( A_MARKER ) ;
  1795.       end loop ;
  1796.     End UPDATE_MARKERS_FOR_ADDED_TEXT ;
  1797.          
  1798.     Procedure UPDATE_MARKERS_FOR_DELETED_TEXT
  1799.                             ( This_Buffer : in an_editor_buffer ;
  1800.                               OLD_TEXT_RANGE : in out TEXT_RANGE ) is
  1801.       -- update all markers because the old text 
  1802.       -- range was deleted
  1803.       A_MARKER : marker_pointer ;
  1804.     Begin
  1805.       A_MARKER := FIRST_IN_LIST ;
  1806.       while A_MARKER /= null loop
  1807.         if a_marker.data.which_buffer = this_buffer then
  1808.           -- OK , we match the current buffer and can work.
  1809.           if gt ( OLD_TEXT_RANGE.LO_POSITION , A_MARKER.DATA ) then
  1810.             null ;  -- marker not affected - marker before deleted range
  1811.           else
  1812.             -- this marker is affected
  1813.             if lt ( A_MARKER.DATA , OLD_TEXT_RANGE.HI_POSITION ) then
  1814.               -- marker inside deleted range  
  1815.               -- set to position immediately before the deleted range
  1816.               A_MARKER.DATA := OLD_TEXT_RANGE.LO_POSITION ;
  1817.             else
  1818.               -- marker past deleted text
  1819.               if A_MARKER.DATA.LINE = OLD_TEXT_RANGE.HI_POSITION.LINE then
  1820.                  -- text deleted in line before this position - column affected
  1821.                 A_MARKER.DATA.COLUMN := A_MARKER.DATA.COLUMN -
  1822.                                         OLD_TEXT_RANGE.HI_POSITION.COLUMN +
  1823.                                         OLD_TEXT_RANGE.LO_POSITION.COLUMN ;
  1824.               else
  1825.                 null ;  -- column not affected
  1826.               end if ;
  1827.               -- obtain new line number for marker
  1828.               A_MARKER.DATA.LINE := A_MARKER.DATA.LINE -
  1829.                                     ( OLD_TEXT_RANGE.HI_POSITION.LINE -
  1830.                                       OLD_TEXT_RANGE.LO_POSITION.LINE ) ;
  1831.             end if ;
  1832.           end if ;
  1833.         end if ;
  1834.         -- obtain next marker to check
  1835.         A_MARKER := NEXT_IN_LIST ( A_MARKER ) ;
  1836.       end loop ;
  1837.     End UPDATE_MARKERS_FOR_DELETED_TEXT ;
  1838.       
  1839.     Procedure CLEAR_MARKERS ( FROM_BUFFER : in an_editor_buffer ) is
  1840.       -- clear all floating markers for lists
  1841.       -- +++ RULE : any marker MUST be disposed.  When a buffer is
  1842.       --            closed .. it must have all markers cleared 
  1843.       --            ( if applicable ).
  1844.       A_MARKER    : marker_pointer ;
  1845.       TEMP_MARKER : marker_pointer ;
  1846.     Begin
  1847.       A_MARKER := FIRST_IN_LIST ;
  1848.       while A_MARKER /= null loop
  1849.         -- get next marker in list
  1850.         TEMP_MARKER := NEXT_IN_LIST ( A_MARKER ) ;
  1851.         if A_MARKER.DATA.WHICH_BUFFER = FROM_BUFFER then
  1852.           -- marker in given buffer, so dispose it.
  1853.           DISPOSE ( A_MARKER ) ;
  1854.         end if ;
  1855.         -- restore to next marker in the list
  1856.         A_MARKER := TEMP_MARKER ;
  1857.       end loop ;
  1858.     End CLEAR_MARKERS ;
  1859.         
  1860.   Begin     -- MARKER_MANAGER ;
  1861.     -- MARKER   by SAIC/Clearwater Marker Manager Package      18 Dec 84
  1862.     null ;
  1863.   End MARKER_MANAGER ;
  1864.      
  1865.   begin -- markers
  1866.     -- MARKERS  by SAIC/Clearwater Marker Packages             26 Dec 84
  1867.     null ;
  1868.   end markers ;
  1869.      
  1870.   --$$$- MARKERS
  1871.  
  1872. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1873. --envirnio
  1874. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1875.  
  1876.   --$$$+ ENVIRNIO
  1877.    
  1878.   --
  1879.   -- File 012
  1880.   --
  1881.   -- Editor Written By Robert S. Cymbalski
  1882.   --                   Science Applications International Corporation
  1883.   --                   Energy Systems Group
  1884.   --                   Ada Software Development Project Team
  1885.   --                   2280 U.S. Highway 19 North, Suite 120
  1886.   --                   Clearwater, Florida  33575
  1887.   --
  1888.   -- Environment Input/Output Routines Written 27 Dec 84 - Robert S. Cymbalski
  1889.   -- 
  1890.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  1891.   -- 
  1892.         
  1893.   with text_io ;
  1894.    
  1895.   with string_library  ;
  1896.   use  string_library  ;
  1897.    
  1898.   with basic_io_system ;
  1899.    
  1900.   with Wordp_Globals   ;
  1901.   use  Wordp_Globals   ;
  1902.  
  1903.   with editor_globals     ;
  1904.   use  editor_globals     ;
  1905.      
  1906.   with markers            ;
  1907.   use  markers            ;
  1908.   use  marker_manager     ;
  1909.    
  1910.   package environment_input_output is
  1911.            
  1912.     procedure convert_string_to_header ( input_string  : in string      ;
  1913.                                          env_code      : in out integer ;
  1914.                                          which_header  : in out header  ;
  1915.                                          markers_buffer: in an_editor_buffer
  1916.                                              ); -- no_buffer ) ;
  1917.        -- Take the Input String as a new line read from a file
  1918.        -- The Environment Code is the Last Environment Line Read In
  1919.        -- and is zero for no lInes read in yet.
  1920.        -- If this line is an environment Line, then modify environment 
  1921.        -- appropriately
  1922.        -- Update env_code to be the next sequential number, or else return
  1923.        -- it as -1 when this line was not processed because it was not part
  1924.        -- of an environment
  1925.         
  1926.     procedure convert_header_to_string ( environment   : in header        ;
  1927.                                          env_code      : in out integer   ;
  1928.                                          new_string    : out pstring    ) ;
  1929.        -- Take the environment specified, and output the line number 
  1930.        -- corresponding to the env_code provided.  Return the string of
  1931.        -- environment data in the string new_string.  Update env_code to the
  1932.        -- next environment code
  1933.    
  1934.     function default_header return header ; 
  1935.        -- Return the standard default header
  1936.         
  1937.     procedure users_default_header ( which_header : in out header );
  1938.        -- Return the user's default header if one exists, else the standard
  1939.         
  1940.   end environment_input_output ;
  1941.      
  1942.   package body environment_input_output is 
  1943.      
  1944.     -- An editor environment is saved in the following format
  1945.      
  1946.     -- The environment ( if it exists ) starts on the very first line .
  1947.     --                                  at the first character position .
  1948.     -- The Environment data is contained in the character positions 6 .. 70
  1949.     -- Positions 1..5 and 71..75 have values which are constant over a
  1950.     -- specified environment, but which can change between files.
  1951.      
  1952.     -- Line 1 Format
  1953.     -- Columns  6.. 9  " 01 "
  1954.     -- Columns 10..21  "SAIC Editor "
  1955.     -- Columns 22..48  File Name of file when last saved (Possibly Truncated)
  1956.     -- Columns 49..57  " Created "
  1957.     -- Columns 58..69  YYMMDD:HH:MM
  1958.     -- Column  70      " "
  1959.      
  1960.     -- Line 2 Format
  1961.     -- Columns  6.. 9  " 02 "
  1962.     -- Columns 10..48  "A=b B=c C=b E=b F=b J=b S=b T=b W=b x=x"
  1963.     -- Columns 49..57  " Updated "
  1964.     -- Columns 58..69  YYMMDD:HH:MM
  1965.     -- Column  70      " "
  1966.      
  1967.     -- Line 3 Format
  1968.     -- Columns  6.. 9  " 03 "
  1969.     -- Columns 10..61  "Left = nnn  Para = nnn  Right = nnn  Markers = nnn  "
  1970.     -- Columns 62..69  "        "
  1971.     -- Column  70      " "
  1972.      
  1973.     -- Line 4 Format
  1974.     -- Columns  6.. 9  " 04 "
  1975.     -- Columns 10..69  Code for Tabs in Positions 1 .. 180
  1976.     -- Column  70      " " 
  1977.      
  1978.     -- Line 5 Format
  1979.     -- Columns  6.. 9  " 05 "
  1980.     -- Columns 10..69  Code for Tabs in Positions 181 .. 360
  1981.     -- Column  70      " " 
  1982.      
  1983.     -- Line 6 Format
  1984.     -- Columns  6.. 9  " 06 "
  1985.     -- Columns 10..69  Code for Tabs in Positions 361 .. 512
  1986.     -- Column  70      " " 
  1987.      
  1988.     -- Line 7 .. Markers + 6 ( if any ) Format
  1989.     -- Columns  6..9   " nn "
  1990.     -- Columns 10..19  Marker Name
  1991.     -- Columns 20..62  " Line Number = nnnnn   Column Number = nnn "
  1992.     -- Columns 63..69  "       "
  1993.     -- Column  70      " "
  1994.      
  1995.     -- Now, misc. routines 
  1996.      
  1997.     function int_to_string_length( number : in integer ;
  1998.                                    length : in integer ) 
  1999.                                    return pstring is
  2000.       new_string : pstring ;
  2001.     begin
  2002.       new_string := int_to_str( number ) ;
  2003.       while string_library.length( new_string ) < length loop
  2004.         new_string := "0" & new_string ;
  2005.       end loop ;
  2006.       return new_string ;
  2007.     end;
  2008.      
  2009.     procedure convert_string_to_header ( input_string  : in string     ;
  2010.                                          env_code      : in out integer;
  2011.                                          which_header  : in out header ;
  2012.                                          markers_buffer: in an_editor_buffer
  2013.                                              ) is  -- no_buffer ) is
  2014.        -- Take the Input String as a new line read from a file
  2015.        -- The Environment Code is the Last Environment Line Read In
  2016.        -- and is zero for no lines read in yet.
  2017.        -- If this line is an environment Line, then modify environment 
  2018.        -- appropriately
  2019.        -- Update env_code to be the next sequential number, or else return
  2020.        -- it as -1 when this line was not processed because it was not part
  2021.        -- of an environment
  2022.        
  2023.       function ok_line_number return boolean is
  2024.         -- s(6..9) should be " nn " where nn is env_code + 1 
  2025.         line_number_string : pstring ;
  2026.       begin
  2027.         line_number_string := int_to_string_length( env_code + 1 , 2 ) ;
  2028.         return ( input_string( 6 ) = ' ' )
  2029.            and ( input_string( 7..8 ) = line_number_string.data( 1 .. 2 ) ) 
  2030.            and ( input_string( 9 ) = ' ' ) ;
  2031.       end;
  2032.        
  2033.       procedure set_first_and_last_five_characters is
  2034.       begin
  2035.         which_header.first_five := input_string( 1 .. 5 ) ;
  2036.         which_header.last_five  := input_string( 71 .. 75 ) ;
  2037.       end ;
  2038.        
  2039.       Function It_Matches_The_Last_Line return boolean is
  2040.       begin
  2041.         return ( which_header.first_five = input_string(  1.. 5 ) )
  2042.            and ( which_header.last_five  = input_string( 71..75 ) ) ;
  2043.       end ;
  2044.      
  2045.       function s_to_i ( s : in string ) return integer is
  2046.         num : integer ;
  2047.         str : string ( 1 .. s'length ) ;
  2048.         -- because of problems with the wicat, only works to 32759
  2049.       begin
  2050.         str := s ;
  2051.         num := 0 ;
  2052.         for position in 1 .. str'length loop
  2053.           if str(position) in '0'..'9' then
  2054.             if num + 9 < integer'last / 10 then
  2055.               num := num * 10 + ( character'pos( str(position) )
  2056.                                 - character'pos('0') ) ;
  2057.             else
  2058.               return 0 ;
  2059.             end if;
  2060.           else
  2061.             return 0;
  2062.           end if;
  2063.         end loop;
  2064.         return num ;
  2065.       end;
  2066.        
  2067.       function to_date ( s : in string ) return basic_io_system.timer is
  2068.         -- Columns 1..12  YYMMDD:HH:MM
  2069.         i        : integer                ;
  2070.         year     : basic_io_system.year_number     ;
  2071.         month    : basic_io_system.month_number    ;
  2072.         day      : basic_io_system.day_number      ;
  2073.         weekday  : basic_io_system.day_of_week_name;
  2074.         hour     : basic_io_system.hour_number     ;
  2075.         minute   : basic_io_system.minute_number   ;
  2076.         second   : basic_io_system.second_number   ;
  2077.         str      : string ( 1 .. s'length ) ;
  2078.         dt       : basic_io_system.timer ;
  2079.       begin
  2080.         str := s ;
  2081.         i    := s_to_i ( str( 1 .. 2 ) ) ;
  2082.         if i > 84 then
  2083.           year := 1900 + i ;
  2084.         else
  2085.           year := 2000 + i ;
  2086.         end if ;
  2087.         i    := s_to_i ( str( 3 .. 4 ) ) ;
  2088.         if i in basic_io_system.month_number then
  2089.           month := i ;
  2090.         else
  2091.           month := 10 ;
  2092.         end if ;
  2093.         i    := s_to_i ( str( 5 .. 6 ) ) ;
  2094.         if i in basic_io_system.day_number then
  2095.           day := i ;
  2096.         else
  2097.           day := 4 ;
  2098.         end if ;
  2099.         weekday := basic_io_system.sunday ;
  2100.         i    := s_to_i ( str( 8 .. 9 ) ) ;
  2101.         if i in basic_io_system.hour_number then
  2102.           hour := i ;
  2103.         else
  2104.           hour := 0 ;
  2105.         end if ;
  2106.         i     :=s_to_i ( str(11 ..12 ) ) ;
  2107.         if i in basic_io_system.minute_number then
  2108.           minute := i ;
  2109.         else
  2110.           minute := 0 ;
  2111.         end if ;
  2112.         second  := 0 ;
  2113.         dt := basic_io_system.time_of ( year , month , day , weekday ,
  2114.                                         hour , minute , second ) ;
  2115.         return dt ;
  2116.       end;
  2117.        
  2118.       procedure do_tabs ( tab_offset : integer ) is
  2119.         -- Columns 10..69  Code for Tabs in Positions 1 .. 180
  2120.         --                                       or 181 .. 360
  2121.         --                                       or 361 .. 512
  2122.         newpla ,
  2123.         whichtab ,
  2124.         presnum  : integer ;
  2125.         filled : array ( 0 .. 5 ) of boolean ;
  2126.         tabpla : integer ;
  2127.       begin -- do_tabs
  2128.         newpla := 10 ; -- column to start with
  2129.         whichtab := 0 ;
  2130.         tabpla   := tab_offset + 1 ;
  2131.         loop
  2132.           if whichtab = 0 then
  2133.             presnum := character'pos(input_string(newpla))-character'pos('@');
  2134.             if presnum < 0 then 
  2135.               presnum := 0 ;
  2136.             end if ;
  2137.             for pla in reverse 0 .. 5 loop
  2138.               filled( pla ) := presnum mod 2 /= 0 ;
  2139.               presnum       := presnum / 2 ;
  2140.             end loop ;
  2141.           end if ;
  2142.           if filled( whichtab ) then
  2143.             which_header.tabline( tabpla ) := tnormal ;
  2144.           elsif filled( whichtab + 1 ) then
  2145.             which_header.tabline( tabpla ) := tnumber ;
  2146.           else
  2147.             which_header.tabline( tabpla ) := tnone   ;
  2148.           end if ;
  2149.           whichtab := whichtab + 2 ;
  2150.           if whichtab = 6 then
  2151.             whichtab := 0 ;
  2152.             newpla := newpla + 1 ;
  2153.           end if;
  2154.         tabpla := tabpla + 1 ;
  2155.         exit when ( tabpla > tab_offset + 180 ) 
  2156.           or else ( tabpla > column_position'last ) ;
  2157.         end loop ;
  2158.       end do_tabs ;
  2159.        
  2160.       procedure do_marker ( marker_num : integer ) is
  2161.         line_number : integer ;
  2162.         line_offset : integer ;
  2163.         mark : markers_array_content ;
  2164.       begin -- do_marker
  2165.         mark.name   :=          input_string( 10 .. 19 ) ;
  2166.         line_number := s_to_i ( input_string( 35 .. 39 ) ) ;
  2167.         line_offset := s_to_i ( input_string( 59 .. 61 ) ) ;
  2168.         new_marker (mark.location);
  2169.         load_marker( mark.location , text_position'
  2170.                                    ( line_number , line_offset , 
  2171.                                    no_screen_attribute , markers_buffer)  );
  2172.         which_header.markers(marker_num) := mark ;
  2173.       end do_marker ;
  2174.          
  2175.       function bool ( c : character ) return boolean is
  2176.       begin
  2177.         return ( c = 'T' ) or else ( c = 't' ) ;
  2178.       end ;
  2179.        
  2180.     begin -- convert_string_to_header 
  2181.       -- What do we do?
  2182.       -- First, check to see if the line number is in position 
  2183.       if input_string'length < 75 then
  2184.         -- not a real line
  2185.         env_code := -1 ;
  2186.       elsif not ok_line_number then
  2187.         env_code := ( -1 ) ;
  2188.       else
  2189.         if env_code = 0 then
  2190.           -- Check for a Special String
  2191.           if input_string ( 10 .. 21 ) = "SAIC Editor " then
  2192.             -- ok..
  2193.             -- we need to load the starting and ending codes
  2194.             set_first_and_last_five_characters ;
  2195.           else
  2196.             -- not ok 
  2197.             env_code := -1;
  2198.             return        ;
  2199.           end if;
  2200.         else
  2201.           if not it_matches_the_last_line then
  2202.             -- no good, not part of the environment
  2203.             env_code := -1;
  2204.             return        ;
  2205.           end if ;
  2206.         end if;
  2207.         -- OK, here on a good line number and starting and ending characters
  2208.         env_code := env_code + 1 ;
  2209.         case env_code is
  2210.         when 1=>which_header.created:=to_date( input_string( 58..69 ));
  2211.         when 2=>which_header.autoindent := bool( input_string( 12 ) ) ;
  2212.                 which_header.break_char :=       input_string( 16 )   ;
  2213.                 which_header.checkcase  := bool( input_string( 20 ) ) ;
  2214.                 which_header.enable_cmds:= bool( input_string( 24 ) ) ;
  2215.                 which_header.filling    := bool( input_string( 28 ) ) ;
  2216.                 which_header.justify    := bool( input_string( 32 ) ) ;
  2217.                 which_header.save_envirn:= bool( input_string( 36 ) ) ;
  2218.                 which_header.Tokdef     := bool( input_string( 40 ) ) ;
  2219.                 which_header.WordProcess:= bool( input_string( 44 ) ) ;
  2220.                 which_header.last_used:=to_date( input_string(58..69));
  2221.         when 3=>which_header.lmargin    := s_to_i ( 
  2222.                                           input_string( 17 .. 19 ) )   ;
  2223.                 which_header.paramargin := s_to_i (
  2224.                                           input_string( 29 .. 31 ) )   ;
  2225.                 which_header.rmargin    := s_to_i (
  2226.                                           input_string( 42 .. 44 ) )   ;
  2227.                 which_header.marker_count:=s_to_i (
  2228.                                           input_string( 57 .. 59 ) )   ;
  2229.                 if which_header.marker_count > max_markers then
  2230.                   env_code := -1;
  2231.                 end if ;
  2232.         when 4=>do_tabs (   0 ) ;
  2233.         when 5=>do_tabs ( 180 ) ;
  2234.         when 6=>do_tabs ( 360 ) ;
  2235.         when others=>if env_code - 6 > which_header.marker_count then
  2236.                        env_code := -1 ;
  2237.                      else
  2238.                        do_marker( env_code - 6 ) ;
  2239.                      end if;
  2240.         end case;
  2241.       end if ;
  2242.     end convert_string_to_header ;
  2243.         
  2244.     procedure convert_header_to_string ( environment   : in header           ;
  2245.                                          env_code      : in out integer      ;
  2246.                                          new_string    : out pstring       ) is
  2247.        -- Take the environment specified, and output the line number 
  2248.        -- corresponding to the env_code provided.  Return the string of
  2249.        -- environment data in the string new_string.  Update env_code to the
  2250.        -- next environment code
  2251.      
  2252.       outs : string ( 1 .. 75 ) :=   -- ( 1 .. 75 => ' ' ) ;
  2253.  "                                                                           ";
  2254.       subtype str2 is string ( 1 .. 2 ) ;
  2255.       subtype str3 is string ( 1 .. 3 ) ;
  2256.       subtype str5 is string ( 1 .. 5 ) ;
  2257.        
  2258.       function to_str2( num : integer ) return str2 is
  2259.         s : pstring ; 
  2260.       begin
  2261.         s := int_to_string_length ( num , 2 ) ;
  2262.         return s.data ( 1 .. 2 ) ;
  2263.       end;
  2264.        
  2265.       function to_str3( num : integer ) return str3 is
  2266.         s : pstring ; 
  2267.       begin
  2268.         s := int_to_string_length ( num , 3 ) ;
  2269.         return s.data ( 1 .. 3 ) ;
  2270.       end;
  2271.        
  2272.       function to_str5( num : integer ) return str5 is
  2273.         s : pstring ; 
  2274.       begin
  2275.         s := int_to_string_length ( num , 5 ) ;
  2276.         return s.data ( 1 .. 5 ) ;
  2277.       end;
  2278.        
  2279.       procedure set_line_number is
  2280.         -- Columns  6.. 9  " nn "
  2281.       begin
  2282.         outs ( 7 .. 8 ) := to_str2( env_code ) ;
  2283.       end;
  2284.        
  2285.       procedure do_line_1 is
  2286.         -- Line 1 Format
  2287.         -- Columns  6.. 9  " 01 "
  2288.         -- Columns 10..21  "SAIC Editor "
  2289.         -- Columns 22..48  File Name when last saved (Possibly Truncated)
  2290.         -- Columns 49..57  " Created "
  2291.         -- Columns 58..69  YYMMDD:HH:MM
  2292.         -- Column  70      " "
  2293.       begin -- do_line_1
  2294.         outs( 10 .. 21 ) := "SAIC Editor " ;
  2295.         if maximum_file_name_length < 27 then
  2296.           -- need to work something else out
  2297.           outs( 22 .. 21 + maximum_file_name_length ) :=
  2298.                                 editor_requested_output_file_name ;
  2299.         else
  2300.           outs( 22 .. 48 ) := editor_requested_output_file_name ( 1 .. 27 ) ;
  2301.         end if ;
  2302.         outs( 49 .. 57 ) := " Created " ;
  2303.         outs( 58 .. 69 ) := "YYMMDD:HH:MM" ;
  2304.         outs( 58 .. 59 ) := to_str2 ( environment.created.year   mod 100 ) ;
  2305.         outs( 60 .. 61 ) := to_str2 ( environment.created.month  ) ;
  2306.         outs( 62 .. 63 ) := to_str2 ( environment.created.day    ) ;
  2307.         outs( 65 .. 66 ) := to_str2 ( environment.created.hour   ) ;
  2308.         outs( 68 .. 69 ) := to_str2 ( environment.created.minute ) ;
  2309.       end do_line_1 ;
  2310.        
  2311.       procedure do_line_2 is
  2312.         -- Line 2 Format
  2313.         -- Columns  6.. 9  " 02 "
  2314.         -- Columns 10..48  "A=b B=c C=b E=b F=b J=b S=b T=b W=b x=x"
  2315.         -- Columns 49..57  " Updated "
  2316.         -- Columns 58..69  YYMMDD:HH:MM
  2317.         -- Column  70      " "
  2318.         new_time : basic_io_system.timer ;
  2319.        
  2320.         function bool ( b : in boolean ) return character is
  2321.         begin
  2322.           if b then
  2323.             return 'T' ;
  2324.           else
  2325.             return 'F' ;
  2326.           end if ;
  2327.         end bool ;
  2328.          
  2329.       begin -- do_line_2
  2330.         outs( 10 .. 48 ) := "A=b B=c C=b E=b F=b J=b S=b T=b W=b x=x" ;
  2331.         outs( 12       ) := bool ( environment.autoindent ) ;
  2332.         outs( 16       ) :=        environment.break_char   ;
  2333.         outs( 20       ) := bool ( environment.checkcase  ) ;
  2334.         outs( 24       ) := bool ( environment.enable_cmds) ;
  2335.         outs( 28       ) := bool ( environment.filling    ) ;
  2336.         outs( 32       ) := bool ( environment.justify    ) ;
  2337.         outs( 36       ) := bool ( environment.save_envirn) ;
  2338.         outs( 40       ) := bool ( environment.Tokdef     ) ;
  2339.         outs( 44       ) := bool ( environment.WordProcess) ;
  2340.         new_time := basic_io_system.clock ;
  2341.         outs( 49 .. 57 ) := " Updated " ;
  2342.         outs( 58 .. 69 ) := "YYMMDD:HH:MM" ;
  2343.         outs( 58 .. 59 ) := to_str2 ( new_time.year   mod 100 ) ;
  2344.         outs( 60 .. 61 ) := to_str2 ( new_time.month  ) ;
  2345.         outs( 62 .. 63 ) := to_str2 ( new_time.day    ) ;
  2346.         outs( 65 .. 66 ) := to_str2 ( new_time.hour   ) ;
  2347.         outs( 68 .. 69 ) := to_str2 ( new_time.minute ) ;
  2348.       end do_line_2 ;
  2349.        
  2350.       procedure do_line_3 is
  2351.         -- Line 3 Format
  2352.         -- Columns  6.. 9  " 03 "
  2353.         -- Cols 10..61  "Left = nnn  Para = nnn  Right = nnn  Markers = nnn  "
  2354.         -- Columns 62..69  "        "
  2355.         -- Column  70      " "
  2356.       begin -- do_line_3
  2357.         outs( 10 .. 61 ) := 
  2358.                       "Left = nnn  Para = nnn  Right = nnn  Markers = nnn  " ;
  2359.         outs( 17 .. 19 ) := to_str3 ( environment.lmargin      ) ;
  2360.         outs( 29 .. 31 ) := to_str3 ( environment.paramargin   ) ;
  2361.         outs( 42 .. 44 ) := to_str3 ( environment.rmargin      ) ;
  2362.         outs( 57 .. 59 ) := to_str3 ( environment.marker_count ) ;
  2363.       end do_line_3 ;
  2364.        
  2365.       procedure do_tabs ( tab_offset : integer ) is
  2366.         -- Columns 10..69  Code for Tabs in Positions 1 .. 180
  2367.         --                                       or 181 .. 360
  2368.         --                                       or 361 .. 512
  2369.         newpla ,
  2370.         whichtab ,
  2371.         presnum  : integer ;
  2372.         add : array ( 0 .. 5 ) of integer ;
  2373.         tabpla : integer ;
  2374.       begin -- do_tabs
  2375.         add(0) := 32 ;
  2376.         add(1) := 16 ;
  2377.         add(2) :=  8 ;
  2378.         add(3) :=  4 ;
  2379.         add(4) :=  2 ;
  2380.         add(5) :=  1 ;
  2381.         newpla := 10 ; -- column to start with
  2382.         whichtab := 0 ;
  2383.         tabpla := tab_offset + 1 ;
  2384.         loop
  2385.           if whichtab = 0 then
  2386.             outs( newpla ) := '@' ;
  2387.           end if ;
  2388.           case environment.tabline( tabpla ) is
  2389.             when tnone         => null                                 ;
  2390.             when tnormal       => outs(newpla) := character'val( 
  2391.                                                   character'pos( outs(newpla))
  2392.                                                   + add(whichtab));
  2393.             when tnumber       => outs(newpla) := character'val( 
  2394.                                                   character'pos( outs(newpla))
  2395.                                                   + add(whichtab+1));
  2396.           end case ;
  2397.           whichtab := whichtab + 2 ;
  2398.           if whichtab = 6 then
  2399.             whichtab := 0 ;
  2400.             newpla := newpla + 1 ;
  2401.           end if;
  2402.         tabpla := tabpla + 1 ;
  2403.         exit when ( tabpla > tab_offset + 180 )
  2404.           or else ( tabpla > column_position'last ) ;
  2405.         end loop ;
  2406.       end do_tabs ;
  2407.        
  2408.       procedure do_line_4 is
  2409.         -- Line 4 Format
  2410.         -- Columns  6.. 9  " 04 "
  2411.         -- Columns 10..69  Code for Tabs in Positions 1 .. 180
  2412.         -- Column  70      " " 
  2413.       begin -- do_line_4
  2414.         do_tabs( 0 ) ;
  2415.       end do_line_4 ;
  2416.        
  2417.       procedure do_line_5 is
  2418.         -- Line 5 Format
  2419.         -- Columns  6.. 9  " 05 "
  2420.         -- Columns 10..69  Code for Tabs in Positions 181 .. 360
  2421.         -- Column  70      " " 
  2422.       begin -- do_line_5
  2423.         do_tabs(180);
  2424.       end do_line_5 ;
  2425.        
  2426.       procedure do_line_6 is
  2427.         -- Line 6 Format
  2428.         -- Columns  6.. 9  " 06 "
  2429.         -- Columns 10..69  Code for Tabs in Positions 361 .. 512
  2430.         -- Column  70      " " 
  2431.       begin -- do_line_6
  2432.         do_tabs(360);
  2433.       end do_line_6 ;
  2434.        
  2435.       procedure do_markers ( marker_num : integer ) is
  2436.         -- Line 7 .. Markers + 6 ( if any ) Format
  2437.         -- Columns  6..9   " nn "
  2438.         -- Columns 10..19  Marker Name
  2439.         -- Columns 20..62  " Line Number = nnnnn   Column Number = nnn "
  2440.         -- Columns 63..69  "       "
  2441.         -- Column  70      " "
  2442.       begin -- do_markers
  2443.         outs ( 10 .. 19 ) := environment.markers( marker_num ).name          ;
  2444.         outs ( 20 .. 62 ) := " Line Number = nnnnn   Column Number = nnn "   ;
  2445.         outs ( 35 .. 39 ) := to_str5( 
  2446.                              environment.markers( marker_num ).location
  2447.                              .data.line);
  2448.         outs ( 59 .. 61 ) := to_str3( 
  2449.                              environment.markers( marker_num ).location
  2450.                              .data.column);
  2451.       end do_markers ;
  2452.        
  2453.     begin -- convert_header_to_string 
  2454.       -- we must take an input code and work it
  2455.       env_code := env_code + 1 ;
  2456.       if env_code - 6 > environment.marker_count then
  2457.         env_code := 0 ;
  2458.       else
  2459.         -- ok, we have to make a line 
  2460.         outs(  1 ..  5 ) := environment.first_five ;
  2461.         for posn in 6 .. 70 loop
  2462.           outs( posn ) := ' ' ;
  2463.         end loop ;
  2464.         outs( 71 .. 75 ) := environment.last_five  ;
  2465.         set_line_number ;
  2466.         case env_code is
  2467.           when 1       => do_line_1 ;
  2468.           when 2       => do_line_2 ;
  2469.           when 3       => do_line_3 ;
  2470.           when 4       => do_line_4 ;
  2471.           when 5       => do_line_5 ;
  2472.           when 6       => do_line_6 ;
  2473.           when others  => do_markers( env_code - 6 ) ;
  2474.         end case;
  2475.       end if ;
  2476.       new_string := string_to_pstring( outs ) ;
  2477.       -- returns something, even if just blank 
  2478.     end convert_header_to_string ;
  2479.    
  2480.     function default_header return header is
  2481.       working_header : header ;
  2482.        
  2483.       function cleared_tab_line return a_tab_line is
  2484.         working_tab_line : a_tab_line ;
  2485.       begin
  2486.         for position in 1 .. max_column_number loop 
  2487.           if position mod 8 = 1 and then
  2488.             position > 1 then
  2489.               working_tab_line( position ) := tnormal ;
  2490.           else
  2491.             working_tab_line( position )   := tnone   ;
  2492.           end if ;
  2493.         end loop ;
  2494.         return working_tab_line ;
  2495.       end cleared_tab_line ;
  2496.         
  2497.     begin -- default_header
  2498.       working_header.filename        := blank_file_name      ;
  2499.       working_header.marker_count    := 0                    ;
  2500.       working_header.autoindent      := false                ;
  2501.       working_header.break_char      := '.'                  ;
  2502.       working_header.checkcase       := false                ;
  2503.       working_header.enable_cmds     := false                ;
  2504.       working_header.filling         := false                ;
  2505.       working_header.hyphenate       := false                ;
  2506.       working_header.justify         := false                ;
  2507.       working_header.save_envirn     := false                ;
  2508.       working_header.tokdef          := false                ;
  2509.       working_header.wordprocess     := false                ;
  2510.       working_header.lmargin         := 0                    ;
  2511.       working_header.rmargin         := basic_io_system.total_crt_col - 2 ;
  2512.       working_header.paramargin      := 0                    ;
  2513.       working_header.created   := basic_io_system.clock ;
  2514.       working_header.last_used := working_header.created ;
  2515.       working_header.first_five      := "?????"              ;
  2516.       working_header.last_five       := "?????"              ;
  2517.       working_header.tabline         := cleared_tab_line ;
  2518.       return working_header ;
  2519.     end default_header ;
  2520.         
  2521.     procedure users_default_header ( which_header : in out header )
  2522.                                   is
  2523.        -- Return the user's default header if one exists, else the standard
  2524.       header_file : text_io.file_type ;
  2525.       input_string : string ( 1 .. 100 ) ;
  2526.       new_string_len : integer ;
  2527.       env_code       : integer ;
  2528.       actual_file_name : ascii_text_file_name ;
  2529.       ok             : boolean ;
  2530.     begin -- users_default_header
  2531.       which_header := default_header ;
  2532.       sok_to_read( default_environment_file_name , actual_file_name , ok ) ;
  2533.       if ok then
  2534.         -- OK , the user has specified a default environment
  2535.         open_for_read(header_file,actual_file_name,ok);
  2536.         if not ok then 
  2537.           -- File not found, even though our own routine told us that it    
  2538.           -- really exists.
  2539.           text_io.close(header_file);
  2540.         else
  2541.           -- OK!
  2542.           env_code := 0 ;
  2543.           loop
  2544.             text_io.get_line(header_file,input_string,new_string_len);
  2545.           exit when text_io.end_of_file(header_file);
  2546.             convert_string_to_header ( input_string( 1 .. new_string_len ) ,
  2547.                                        env_code , which_header , no_buffer );
  2548.           exit when ( env_code < 0 ) ;
  2549.           end loop ;
  2550.           text_io.close(header_file);
  2551.         end if ; -- we actually had a file out there 
  2552.       end if ;
  2553.       which_header.created   := basic_io_system.clock ;
  2554.       which_header.last_used := which_header.created ;
  2555.     end users_default_header ;
  2556.      
  2557.   begin -- environment_input_output
  2558.     -- ENVIRNIO by SAIC/Clearwater Environment Input/Output    27 Dec 84
  2559.     null ;
  2560.   end environment_input_output ;
  2561.     
  2562.   --$$$- ENVIRNIO
  2563.  
  2564. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2565. --buffers
  2566. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2567.  
  2568.   --$$$+ BUFFERS
  2569.    
  2570.   -- File 013
  2571.   --
  2572.   -- Editor Written By Robert S. Cymbalski
  2573.   --                   Science Applications International Corporation
  2574.   --                   Energy Systems Group
  2575.   --                   Ada Software Development Project Team
  2576.   --                   2280 U.S. Highway 19 North, Suite 120
  2577.   --                   Clearwater, Florida  33575
  2578.   --
  2579.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  2580.   -- 
  2581.          
  2582.   with text_io        ;
  2583.   with io_exceptions  ;
  2584.   use  io_exceptions  ;
  2585.    
  2586.   with direct_io      ;
  2587.    
  2588.   with string_library ;
  2589.   use  string_library ;
  2590.    
  2591.   with Wordp_Globals  ;
  2592.   use  Wordp_Globals  ;
  2593.  
  2594.   with editor_globals ;
  2595.   use  editor_globals ;
  2596.    
  2597.   with edit_windows   ;
  2598.   use  edit_windows   ;
  2599.      
  2600.   -- with debugger ;
  2601.   -- use  debugger ;
  2602.     
  2603.   with environment_input_output ;
  2604.   use  environment_input_output ;
  2605.    
  2606.   with markers               ;
  2607.   use  markers               ;
  2608.   use  text_position_handler ;
  2609.   use  marker_manager        ;
  2610.    
  2611.   package buffer_package is
  2612.    
  2613.     package buffer_block_io is
  2614.                
  2615.     --
  2616.     -- Block I/O written to bypass problems with wicat
  2617.     --                   Written 19 Dec 84 - RSCymbalski
  2618.     --
  2619.        
  2620.       procedure create  ( which_buffer : in out an_editor_buffer ;
  2621.                           the_file     : in     topush           ;
  2622.                           successfull  :    out boolean          ) ;
  2623.                  -- open the file for input and output 
  2624.        
  2625.       procedure close   ( which_buffer : in out an_editor_buffer ;
  2626.                           the_file     : in     topush           ;
  2627.                           successfull  :    out boolean          ) ;
  2628.                  -- close the file 
  2629.        
  2630.       procedure getblock( which_buffer : in out an_editor_buffer ;
  2631.                           the_file     : in     topush           ;
  2632.                           block_of_data: out    block            ;
  2633.                           block_number : in     integer          ;
  2634.                           successfull  : out    boolean          ) ;   
  2635.                  -- read in a block of data from that file
  2636.        
  2637.       procedure putblock( which_buffer : in out an_editor_buffer ;
  2638.                           the_file     : in     topush           ;
  2639.                           block_of_data: in     block            ;
  2640.                           block_number : in     integer          ;
  2641.                           successfull  : out    boolean          ) ;   
  2642.                  -- write a block of data from that file
  2643.        
  2644.     end buffer_block_io ;
  2645.      
  2646.     package buffer_general is
  2647.      
  2648.       procedure move_buffer_area_to_block( which_buffer : an_editor_buffer     ;
  2649.                                            start_pos    : type_buffer_position ;
  2650.                                            block_of_data: out block          ) ;
  2651.         -- Move the buffer data starting at start_pos to the block of data
  2652.                
  2653.       procedure move_block_to_buffer_area( which_buffer:in out an_editor_buffer;
  2654.                                            block_of_data: in block             ;
  2655.                                            start_pos    : type_buffer_position);
  2656.         -- Move the block of data to the buffer at start pos
  2657.                
  2658.       procedure shift_buffer_area( which_buffer : in out an_editor_buffer;
  2659.                                    source       : type_buffer_position   ;
  2660.                                    destination  : type_buffer_position   ;
  2661.                                    length       : type_buffer_position ) ;
  2662.         -- Shift data in the buffer from the source position to the 
  2663.         -- destination position, and then continue for length positions
  2664.         -- If the destination is to the right of the source, then do it
  2665.         -- in the reverse direction!
  2666.                                       
  2667.       procedure adjust_cursors( which_buffer : in out an_editor_buffer ;
  2668.                                 amount_added : in integer            ) ;
  2669.         -- adjust the (4) cursors within a buffer because we have added
  2670.         -- or subtracted the specified number of buffer positions.  
  2671.         -- If any position becomes invalid, mark as line_start = 0
  2672.          
  2673.       procedure open_buffer( which_buffer : in out an_editor_buffer ;
  2674.                              line_start   : in type_buffer_position ;
  2675.                              required_area: in integer              ) ; 
  2676.                  -- Open an area in the buffer which will facilitate
  2677.                  -- the addition of at least the required area of 
  2678.                  -- bytes.  Start moving text from the line_start specified
  2679.    
  2680.       procedure close_buffer( which_buffer : in out an_editor_buffer ) ;
  2681.         -- Close up the opened area in the buffer 
  2682.    
  2683.       procedure push_data( which_buffer : in out an_editor_buffer ;
  2684.                            from         : in topush               ;
  2685.                            successfull  : out boolean             ) ; 
  2686.                  -- Push information to thetop or thebot of the file
  2687.                  -- return true if successfull
  2688.                        
  2689.       procedure pop_data( which_buffer : in out an_editor_buffer ;
  2690.                           from         : in topush               ;
  2691.                           successfull  : out boolean             ) ; 
  2692.                  -- Pop information from thetop or thebot of the 
  2693.                  -- file, if any exists.
  2694.                  -- return true if successfull
  2695.                        
  2696.       procedure interpret_string ( in_string      : in string               ;
  2697.                                    leading_blanks : out type_leading_spaces ;
  2698.                                    first_character: out type_text_length    ;
  2699.                                    last_character : out type_text_length    ;
  2700.                                    length         : out type_line_length  ) ;
  2701.                  -- Take the input string and interpret it by our rules
  2702.         
  2703.       procedure read_next_line ( which_buffer : in out an_editor_buffer ;
  2704.                                  env_code     : in out integer ) ;
  2705.                  -- Read the next line into an open buffer
  2706.                  -- the env_code is a code to keep track of the environment
  2707.                  -- when we are reading it.
  2708.                   
  2709.     end buffer_general ;
  2710.      
  2711.     package buffer_lines is
  2712.     
  2713.       buffer_boundry : constant integer := 255 ;
  2714.              
  2715.       function Line_Length ( which_buffer    : in an_editor_buffer     ;
  2716.                              starting_pos    : in type_buffer_position )
  2717.                              return type_line_length ;
  2718.         -- Return the line length of the line starting here
  2719.             
  2720.       function Num_Leading_Spaces ( which_buffer    : in an_editor_buffer     ;
  2721.                                 starting_pos    : in type_buffer_position )
  2722.                                 return type_leading_spaces ;
  2723.         -- Return the leading spaces on the line starting here
  2724.             
  2725.       function num_leading_spaces( which_buffer : in an_editor_buffer ;
  2726.                                a_cursor     : in cursor_position )
  2727.                                return type_leading_spaces ; 
  2728.         -- Return leading spaces on the cursor line
  2729.          
  2730.       procedure get_line_info( which_buffer     : in an_editor_buffer      ;
  2731.                                starting_position: in type_buffer_position  ;
  2732.                                leading_spaces   : out type_leading_spaces  ;
  2733.                                first_text_position,
  2734.                                last_text_position:out type_buffer_position ;
  2735.                                length    : out type_line_length  );
  2736.                  --  The buffer and a pointer to the current line's starting
  2737.                  --  position are provided.  Note that this starting position
  2738.                  --  is a pointer to the starting line length for the line.
  2739.                  --  The number of leading spaces and pointers to the first
  2740.                  --  and last characters on the line are returned.  Also, 
  2741.                  --  the count of the number of characters is provided.
  2742.             
  2743.       procedure ot_line( which_buffer : in an_editor_buffer      ;
  2744.                          line         : in window_line_number ;
  2745.                          column       : in window_column_number ;
  2746.                          first_text   ,
  2747.                          last_text    : in type_buffer_position );
  2748.                  --  The buffer is provided, as well as the line
  2749.                  --  and column to start with when displaying text.
  2750.                  --  the actual text exists from first_text to 
  2751.                  --  last_text in the buffer.  Output it IF it fits
  2752.                  --  within the current editor window.
  2753.                         
  2754.       procedure ot_line( which_buffer : in an_editor_buffer      ;
  2755.                          line         : in window_line_number  ;
  2756.                          column       : in window_column_number;
  2757.                          Line_Of_Text : in type_text_line      ) ;
  2758.                  --  The buffer is provided, as well as the line
  2759.                  --  and column to start with when displaying text.
  2760.                  --  the actual text exists in Line_Of_Text
  2761.                  --  Output it IF it fits within the current editor window.
  2762.                  --  Note that we will have to skip the first 
  2763.                  --  spaces (designated by leading_spaces) because they
  2764.                  --  are already included in the starting screen position
  2765.                         
  2766.       procedure get_text_line( which_buffer     : in an_editor_buffer      ;
  2767.                                starting_position: in type_buffer_position  ;
  2768.                                Line_Of_Text     : out type_text_line     ) ;
  2769.                  --  The buffer and a pointer to the current line's starting
  2770.                  --  position are provided.  Note that this starting position
  2771.                  --  is an entity which cannot be manipulated by the caller
  2772.                  --  The number of leading spaces , the length of the text
  2773.                  --  in the line, and the actual text line are returned.
  2774.            
  2775.       procedure show_line( which_buffer         : in an_editor_buffer      ;
  2776.                            starting_position    : in type_buffer_position  ;
  2777.                            line_number_within_file : in Line_Number        ;
  2778.                            move_to_starting_pos : in boolean := true       );
  2779.                  --  The buffer and a pointer to the current line's starting
  2780.                  --  position are provided.  Also, the actual line number
  2781.                  --  within the file is sent.  This routine sends the text
  2782.                  --  line to the screen.
  2783.                        
  2784.       procedure show_line( which_buffer         : in an_editor_buffer      ;
  2785.                            Line_Of_Text         : in type_text_line        ;
  2786.                            line_Number_within_file : in Line_Number        ;
  2787.                            move_to_starting_pos : in boolean := true       ) ;
  2788.                  --  The buffer and the line of text to put on the screen    
  2789.                  --  are provided.  Also, the actual line number within the 
  2790.                  --  file is sent.  This routine sends the text
  2791.                  --  line to the screen.
  2792.       
  2793.       procedure line_forward( which_buffer  : in out an_editor_buffer   ) ;
  2794.                  --  The buffer and starting position of the current line
  2795.                  --  are provided.  Returns the starting position of the
  2796.                  --  line immediately following the old line.  If the new
  2797.                  --  location is the same as the starting position, then
  2798.                  --  movement was not possible.
  2799.                  --  moves from fixed_cursor.linestart and sets moving_cursor
  2800.         
  2801.       procedure line_backward(which_buffer  : in out an_editor_buffer   ) ;
  2802.                  --  The buffer and starting position of the current line
  2803.                  --  are provided.  Returns the starting position of the
  2804.                  --  line immediately before the old line.  If the new
  2805.                  --  location is the same as the starting position, then
  2806.                  --  movement was not possible.
  2807.                  --  moves from fixed_cursor.linestart and sets moving_cursor
  2808.                        
  2809.       procedure set_cursor_up_lines ( which_buffer : in out an_editor_buffer ;
  2810.                                       old_cursor   : in cursor_position      ;
  2811.                                       new_cursor   : out cursor_position     ;
  2812.                                       lines_up     : integer               ) ;
  2813.         
  2814.       procedure set_cursor_down_lines(which_buffer : in out an_editor_buffer ;
  2815.                                       old_cursor   : in cursor_position      ;
  2816.                                       new_cursor   : out cursor_position     ;
  2817.                                       lines_down   : integer               ) ;
  2818.         
  2819.       procedure put_cursor_on_line ( which_buffer : in out an_editor_buffer ;
  2820.                                      this_line : in window_line_number ) ;
  2821.        
  2822.       procedure memory_center ( which_buffer : in out an_editor_buffer ;
  2823.                                 new_line_number : in window_line_number := 0 ) ;
  2824.         -- center the buffer's cursor in memory so that we can place the
  2825.         -- cursor anywhere on the screen and feel safe that we will not run
  2826.         -- out of text in memory
  2827.        
  2828.       function cursor_off_screen ( which_buffer : in an_editor_buffer ) 
  2829.                                           return boolean ;
  2830.       
  2831.     end buffer_lines ;
  2832.           
  2833.     procedure re_initialize ( which_buffer : in out an_editor_buffer ) ;
  2834.       -- Do the initialization which is also done each time a buffer
  2835.       -- is re_loaded
  2836.      
  2837.     procedure initialize_buffer( which_buffer : out an_editor_buffer ;
  2838.                                  buffer_number: in a_buffer_number   ) ; 
  2839.                -- Initialize the buffer.
  2840.                   
  2841.     procedure load_file( which_buffer : in out an_editor_buffer ;
  2842.                          file_to_load : in ascii_text_file_name ) ; 
  2843.                -- Load the named file into the buffer.  We can assume
  2844.                -- an empty buffer in this case.
  2845.                   
  2846.     procedure copy_file( which_buffer : in out an_editor_buffer ;
  2847.                          file_to_copy : in ascii_text_file_name ;
  2848.                          first_marker : in str10 ;
  2849.                          last_marker  : in str10 ) ;  
  2850.                -- Copy the named file in at the current position in 
  2851.                -- which buffer.
  2852.                   
  2853.     procedure dispose_buffer( which_buffer : in out an_editor_buffer ) ;
  2854.       -- close a buffer because we are done with it
  2855.          
  2856.   end buffer_package ;
  2857.         
  2858.   package body buffer_package is
  2859.         
  2860.   package body buffer_block_io is
  2861.    
  2862.     package edit_block_io is new direct_io(block);
  2863.      
  2864.     type single_buffer_files    is array ( topush ) of edit_block_io.file_type ;
  2865.      
  2866.     buffer_files                :  array ( a_buffer_number range
  2867.                                            1 .. max_buffer_number ) 
  2868.                                            of single_buffer_files ;
  2869.                                             
  2870.     procedure create  ( which_buffer : in out an_editor_buffer ;
  2871.                         the_file     : in     topush           ;
  2872.                         successfull  :    out boolean          ) is
  2873.                -- open the file for input and output 
  2874.     begin -- create
  2875.       edit_block_io.create( buffer_files( which_buffer.buffer_number )
  2876.                                         ( the_file ) ,
  2877.                             edit_block_io.inout_file);
  2878.       successfull := true ; 
  2879.     exception 
  2880.       when others                    => successfull := false ;
  2881.     end create ;
  2882.      
  2883.     procedure close   ( which_buffer : in out an_editor_buffer ;
  2884.                         the_file     : in     topush           ;
  2885.                         successfull  :    out boolean          ) is
  2886.                -- close the temporary file 
  2887.     begin -- close
  2888.       edit_block_io.close ( buffer_files( which_buffer.buffer_number )
  2889.                                         ( the_file ) ) ;
  2890.       successfull := true ; 
  2891.     exception 
  2892.       when others                    => successfull := false ;
  2893.     end close ;
  2894.      
  2895.     procedure getblock( which_buffer : in out an_editor_buffer ;
  2896.                         the_file     : in     topush           ;
  2897.                         block_of_data: out    block            ;
  2898.                         block_number : in     integer          ;
  2899.                         successfull  : out    boolean          ) is  
  2900.                -- read in a block of data from that file
  2901.     begin -- getblock
  2902.       edit_block_io.read( buffer_files( which_buffer.buffer_number )
  2903.                                       ( the_file ) ,
  2904.                           block_of_data ,
  2905.                           edit_block_io.positive_count(block_number)) ;
  2906.       successfull := true ; 
  2907.     exception 
  2908.       when others                    => successfull := false ;
  2909.     end getblock ;
  2910.      
  2911.     procedure putblock( which_buffer : in out an_editor_buffer ;
  2912.                         the_file     : in     topush           ;
  2913.                         block_of_data: in     block            ;
  2914.                         block_number : in     integer          ;
  2915.                         successfull  : out    boolean          ) is  
  2916.                -- write a block of data from that file
  2917.       wicat_block : block := block_of_data ;
  2918.     begin -- putblock
  2919.       -- since this crazy wicat does not match the LRM, we must do a 
  2920.       -- temp variable!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  2921.       edit_block_io.write(buffer_files( which_buffer.buffer_number )
  2922.                                       ( the_file ) ,
  2923.                           wicat_block   ,
  2924.                           edit_block_io.positive_count(block_number)) ;
  2925.       successfull := true ; 
  2926.     exception 
  2927.       when others                    => successfull := false ;
  2928.     end putblock ;
  2929.      
  2930.   begin -- buffer_block_io 
  2931.     -- BUFFBLOK by SAIC/Clearwater Buffer Block I/O            19 Dec 84
  2932.     null ;
  2933.   end buffer_block_io ;
  2934.    
  2935.   use  buffer_block_io;
  2936.    
  2937.   package body buffer_general is 
  2938.      
  2939.     procedure move_buffer_area_to_block( which_buffer : an_editor_buffer     ;
  2940.                                          start_pos    : type_buffer_position ;
  2941.                                          block_of_data: out block         ) is
  2942.       -- Move the buffer data starting at start_pos to the block of data
  2943.     begin -- move_buffer_area_to_block 
  2944.       for position in 0 .. block_minus loop
  2945.         block_of_data( position ) := which_buffer.e_buf( start_pos + position );
  2946.       end loop ;
  2947.       -- block_of_data ( 0 .. block_minus )
  2948.       -- := which_buffer.e_buf( start_pos .. start_pos + block_size - 1 ) ;
  2949.     end move_buffer_area_to_block ;
  2950.              
  2951.     procedure move_block_to_buffer_area( which_buffer:in out an_editor_buffer;
  2952.                                          block_of_data: in block             ;
  2953.                                          start_pos    :type_buffer_position) is
  2954.       -- Move the block of data to the buffer at start pos
  2955.     begin -- move_block_to_buffer_area 
  2956.       for position in 0 .. block_minus loop
  2957.         which_buffer.e_buf( start_pos + position ):= block_of_data(position);
  2958.       end loop ;
  2959.       -- which_buffer.e_buf( start_pos .. start_pos + block_size - 1 ) 
  2960.                -- := block_of_data ( 0 .. block_minus ) ;
  2961.     end move_block_to_buffer_area ;
  2962.        
  2963.     procedure shift_buffer_area( which_buffer : in out an_editor_buffer;
  2964.                                  source       : type_buffer_position   ;
  2965.                                  destination  : type_buffer_position   ;
  2966.                                  length       : type_buffer_position ) is
  2967.       -- Shift data in the buffer from the source position to the 
  2968.       -- destination position, and then continue for length positions
  2969.       -- If the destination is to the right of the source, then do it
  2970.       -- in the reverse direction!
  2971.     begin -- shift_buffer_area 
  2972.       if length > 0 then
  2973.         if source > destination then
  2974.           -- we are moving left
  2975.           for counter in 0 .. length - 1 loop
  2976.             which_buffer.e_buf( destination + counter ) 
  2977.                 := which_buffer.e_buf( source + counter ) ;
  2978.           end loop ;
  2979.         else
  2980.           -- either a no-op if identical, or move right
  2981.           for counter in reverse 0 .. length - 1 loop
  2982.             which_buffer.e_buf( destination + counter ) 
  2983.                 := which_buffer.e_buf( source + counter ) ;
  2984.           end loop ;
  2985.         end if ;
  2986.       end if ;
  2987.     end shift_buffer_area ;
  2988.        
  2989.     procedure adjust_cursors( which_buffer : in out an_editor_buffer ;
  2990.                               amount_added : in integer            ) is
  2991.       -- adjust the (4) cursors within a buffer because we have added
  2992.       -- or subtracted the specified number of buffer positions.  
  2993.       -- If any position becomes invalid, mark as line_start = 0
  2994.       lowest_position : constant type_buffer_position := 1 ;
  2995.       highest_position : type_buffer_position ;
  2996.        
  2997.       procedure adjust ( cursor : in out cursor_position ) is
  2998.         new_position : integer ;
  2999.       begin
  3000.         cursor.buffer_position := 0 ;
  3001.         if cursor.line_start /= 0 then
  3002.           -- we only work it if it is not a zero....
  3003.           new_position := cursor.line_start + amount_added ;
  3004.           if ( new_position >= lowest_position ) 
  3005.           and then ( new_position <= highest_position ) then
  3006.             cursor.line_start := new_position ;
  3007.           else
  3008.             cursor.line_start := 0 ;
  3009.           end if ;
  3010.         end if ;
  3011.       end;
  3012.        
  3013.     begin -- adjust_cursors 
  3014.       -- work with : which_buffer.fixed_cursor
  3015.       --                         .floating_cursor
  3016.       --                         .moving_cursor
  3017.       --                         .top_screen_cursor
  3018.       --                         .next_screen_cursor
  3019.       -- each has .buffer_position  : type_buffer_position 
  3020.       --          .file_line_number : line_number
  3021.       --          .line_start       : type_buffer_position
  3022.       --          .column_offset    : column_position
  3023.       --
  3024.       -- text_io.put("<");
  3025.       if which_buffer.open_buffer_area then
  3026.         -- we are only working within the first half of the buffer
  3027.         highest_position := which_buffer.first_open_position - 1;
  3028.       else
  3029.         highest_position := which_buffer.bufcount ;
  3030.       end if ;
  3031.       adjust( which_buffer.fixed_cursor               ) ;
  3032.       adjust( which_buffer.floating_cursor            ) ;
  3033.       adjust( which_buffer.moving_cursor              ) ;
  3034.       adjust( which_buffer.top_screen_cursor          ) ;
  3035.       adjust( which_buffer.next_screen_cursor         ) ;
  3036.       -- if ( which_buffer.top_screen_cursor.line_start = 0 ) then
  3037.         -- which_buffer.next_screen_cursor.line_start := 0 ;
  3038.       -- end if ; -- just in case
  3039.       -- text_io.put(">");
  3040.     end adjust_cursors ;
  3041.      
  3042.     procedure open_buffer( which_buffer : in out an_editor_buffer ;
  3043.                            line_start   : in type_buffer_position ;
  3044.                            required_area: in integer              ) is
  3045.                -- Open an area in the buffer which will facilitate
  3046.                -- the addition of at least the required area of 
  3047.                -- bytes.  Start moving text from the line_start specified
  3048.       successfull : boolean := true ;
  3049.       positions_to_move : integer ;
  3050.       move_to           : type_buffer_position ;
  3051.       final_line_start  : type_buffer_position ;
  3052.     begin -- open_buffer 
  3053.       -- The Physical Buffer is defined from 0 .. Max_Buffer_Size  
  3054.       -- Actual Data resides in buffer  from 1 .. which_buffer.bufcount
  3055.       -- 1st Step: Empty The buffer enough to make the required area open
  3056.       final_line_start := line_start ;
  3057.       loop
  3058.       exit when max_buffer_size - which_buffer.bufcount > required_area ;
  3059.         if final_line_start < which_buffer.bufcount - block_size then
  3060.           -- we want to push from the bottom 
  3061.           push_data( which_buffer , thebot , successfull ) ;
  3062.       exit when not successfull ;
  3063.         else
  3064.       exit when final_line_start <= block_size ;
  3065.           push_data( which_buffer , thetop , successfull ) ;
  3066.       exit when not successfull ;
  3067.           final_line_start := final_line_start - block_size ;
  3068.         end if ;
  3069.       end loop ;
  3070.       -- 2nd Step: Open the buffer 
  3071.       positions_to_move := which_buffer.bufcount - final_line_start + 1 ;
  3072.       move_to           := max_buffer_size - positions_to_move + 1 ;
  3073.       shift_buffer_area( which_buffer , final_line_start , move_to , 
  3074.                                         positions_to_move  ) ;
  3075.       -- 3rd Step: Set The actual values
  3076.       which_buffer.open_buffer_area := true ;
  3077.       which_buffer.first_open_position:= final_line_start ;
  3078.       which_buffer.last_open_position := move_to - 1 ;
  3079.       which_buffer.bufcount := max_buffer_size ;
  3080.       if not successfull then
  3081.         error("Unable To Correctly Read/Write Temporary Files.",
  3082.               not_fatal_error,operator_wait,medium_beep);
  3083.       end if ;
  3084.     end open_buffer ;
  3085.      
  3086.     procedure close_buffer( which_buffer : in out an_editor_buffer ) is
  3087.       -- Close up the opened area in the buffer 
  3088.       positions_to_move : integer ;
  3089.     begin -- close_buffer
  3090.       positions_to_move := which_buffer.bufcount 
  3091.                                            - which_buffer.last_open_position ;
  3092.       shift_buffer_area( which_buffer , which_buffer.last_open_position + 1 ,
  3093.                                         which_buffer.first_open_position ,
  3094.                                         positions_to_move ) ;
  3095.       which_buffer.open_buffer_area := false ;
  3096.       which_buffer.bufcount := which_buffer.first_open_position - 1 
  3097.                                + positions_to_move ;
  3098.     end close_buffer ;
  3099.      
  3100.     procedure push_data( which_buffer : in out an_editor_buffer ;
  3101.                          from         : in topush               ;
  3102.                          successfull  : out boolean             ) is
  3103.                -- Push information to thetop or thebot of the file
  3104.                -- return true if successfull
  3105.       last_move_position : type_buffer_position ;
  3106.       first_move_position: type_buffer_position ;
  3107.       positions_to_move  : type_buffer_position ;
  3108.       block_of_data : block ;
  3109.       new_block     : integer ;
  3110.       temp_successfull : boolean := false ;
  3111.     begin -- push_data
  3112.       successfull := false ;
  3113.       if from = thetop then
  3114.         -- text_io.put("[Push Top #");
  3115.          
  3116.         -- Push a block of text from the beginning of the text buffer onto
  3117.         -- a stack of blocks
  3118.         -- First, make sure we have room
  3119.         if which_buffer.open_buffer_area then
  3120.           -- we are pushing while the buffer is open.  
  3121.           last_move_position := which_buffer.first_open_position - 1 ;
  3122.             -- That is the last character position to move after push
  3123.         else
  3124.           -- the buffer is not open
  3125.           last_move_position := which_buffer.bufcount ;
  3126.         end if ;
  3127.         if block_size <= last_move_position then
  3128.           -- we are here when the size of a block ( 1024 ) is less than
  3129.           -- the number of characters available to push so that 
  3130.           -- we definitely have 1024 characters we are prepared to push
  3131.           new_block := which_buffer.prestopblock + 1 ;
  3132.           -- We increment to the next top block to write.  We start with
  3133.           -- prestopblock set to 0, and the first written block is numbered
  3134.           -- #1
  3135.           move_buffer_area_to_block( which_buffer , 1 , block_of_data ) ;
  3136.            
  3137.           putblock( which_buffer , thetop , block_of_data , new_block ,
  3138.                                                             temp_successfull );
  3139.           if temp_successfull then
  3140.             -- here if the block is put correctly...
  3141.             -- text_io.put(" ok ");
  3142.             which_buffer.prestopblock := new_block ;
  3143.             positions_to_move := last_move_position - block_size ;
  3144.             shift_buffer_area( which_buffer , block_size + 1 , 1 ,
  3145.                                positions_to_move ) ;
  3146.             -- shifts within which_buffer, from block_size + 1 to 
  3147.             -- position 1.  Positions_to_move Positions
  3148.             if which_buffer.open_buffer_area then
  3149.               -- we are pushing while the buffer is open.  
  3150.               -- last_move_position := which_buffer.first_open_position - 1 ;
  3151.               -- That is the last character position to move after push
  3152.               which_buffer.first_open_position 
  3153.                     := which_buffer.first_open_position - block_size ;
  3154.             else
  3155.               -- the buffer is not open
  3156.               -- last_move_position := which_buffer.bufcount
  3157.               which_buffer.bufcount := which_buffer.bufcount - block_size ;
  3158.             end if ;
  3159.             -- Now, is there anything else to do? Yes. We must reset the
  3160.             -- cursor offset.
  3161.             adjust_cursors( which_buffer , - block_size ) ;
  3162.           -- else -- cannot write block out
  3163.           end if;
  3164.         -- else -- don't have enough stuff to be able to push
  3165.         end if ;  -- we had or did not have enough data to move 
  3166.          
  3167.       else        
  3168.            
  3169.         -- text_io.put("[Push Bot #");
  3170.         -- Push a block of text from the end of the text buffer onto
  3171.         -- a stack of blocks
  3172.         -- First, make sure we have room
  3173.         if which_buffer.open_buffer_area then
  3174.           -- we are pushing while the buffer is open.  
  3175.           first_move_position := which_buffer.last_open_position + 1 ;
  3176.           -- That is the last character position to move after push  
  3177.         else
  3178.           -- the buffer is not open
  3179.           first_move_position := 1 ;
  3180.         end if ;
  3181.         if block_size <= which_buffer.bufcount - first_move_position + 1  then
  3182.           -- we are here when the size of a block ( 1024 ) is less than
  3183.           -- the number of characters available to push so that 
  3184.           -- we definitely have 1024 characters we are prepared to push
  3185.           new_block := which_buffer.presbotblock + 1 ;
  3186.           -- We increment to the next top block to write.  We start with
  3187.           -- prestopblock set to 0, and the first written block is numbered
  3188.           -- #1
  3189.           move_buffer_area_to_block( which_buffer , 
  3190.                                      which_buffer.bufcount - block_size + 1 ,
  3191.                                      block_of_data ) ;
  3192.           putblock( which_buffer , thebot , block_of_data , new_block ,
  3193.                                                             temp_successfull );
  3194.           if temp_successfull then
  3195.             -- here if the block is put correctly...
  3196.             -- text_io.put(" ok ");
  3197.             which_buffer.presbotblock := new_block ;
  3198.             if which_buffer.open_buffer_area then
  3199.               -- we are pushing while the buffer is open.  
  3200.               which_buffer.last_open_position 
  3201.                     := which_buffer.last_open_position + block_size ;
  3202.               positions_to_move := which_buffer.bufcount 
  3203.                                             - first_move_position + 1 
  3204.                                             - block_size ;
  3205.               shift_buffer_area(which_buffer,first_move_position ,
  3206.                                              first_move_position + block_size,
  3207.                                              positions_to_move ) ;
  3208.               -- shifts within which_buffer, towards the end of the buffer
  3209.             else
  3210.               -- the buffer is not open
  3211.               -- first_move_position := which_buffer.bufcount
  3212.               which_buffer.bufcount := which_buffer.bufcount - block_size ;
  3213.             end if ;
  3214.             -- Now, is there anything else to do? Yes. We must reset the
  3215.             -- cursor offset.
  3216.             -- Since the cursor cannot be in the second part, skip it
  3217.           -- else -- cannot write block out
  3218.           end if;
  3219.         -- else -- don't have enough stuff to be able to push
  3220.         end if ;  -- we had or did not have enough data to move 
  3221.          
  3222.       end if ;
  3223.       -- text_io.put(" PushEnd]");
  3224.       successfull := temp_successfull ;
  3225.     end push_data ;
  3226.        
  3227.     procedure pop_data( which_buffer : in out an_editor_buffer ;
  3228.                         from         : in topush               ;
  3229.                         successfull  : out boolean             ) is
  3230.                -- Pop information from thetop or thebot of the 
  3231.                -- file, if any exists.
  3232.                -- return true if successfull
  3233.       block_of_data : block ;
  3234.       highest_position : type_buffer_position ;
  3235.       need_to_push : boolean ;
  3236.       temp_successfull : boolean := false ;
  3237.        
  3238.       procedure read_new_data is
  3239.         garbage : integer := -1 ;
  3240.       begin -- read_new_data
  3241.         open_buffer( which_buffer , which_buffer.bufcount  
  3242.                                   , block_size + max_bytes_in_line 
  3243.                                                + max_bytes_in_line );
  3244.         -- open up the buffer and guarantee us that we will have room
  3245.         -- to read in an entire block ( and since it is not exact , we
  3246.         -- might have up to two extra lines
  3247.         -- we will end when open area is <= 2 * max_bytes_in_line
  3248.         loop
  3249.           read_next_line ( which_buffer , garbage ) ; 
  3250.         exit when not which_buffer.still_reading_input_file ;
  3251.         exit when which_buffer.last_open_position 
  3252.                 - which_buffer.first_open_position + 1 <= max_bytes_in_line 
  3253.                                                         + max_bytes_in_line ;
  3254.         end loop ;
  3255.         close_buffer(which_buffer);
  3256.       end read_new_data ;
  3257.         
  3258.     begin -- pop_data
  3259.       if ( ( from = thetop ) and ( which_buffer.prestopblock > 0 ) ) 
  3260.       or ( ( from = thebot ) and ( ( which_buffer.presbotblock > 0 ) 
  3261.                                or  which_buffer.still_reading_input_file ) )
  3262.                                                then
  3263.         -- We are here and know that we must do something
  3264.         -- First, make some room if necessary 
  3265.         -- put(" Pop The ");
  3266.         -- if from = thetop then
  3267.           -- put("TOP");
  3268.         -- else
  3269.           -- put("BOT");
  3270.         -- end if ;
  3271.         if which_buffer.open_buffer_area then
  3272.           -- we are only working within the first half of the buffer
  3273.           highest_position := which_buffer.first_open_position - 1;
  3274.           need_to_push     := false ; -- if we opened buffer, must have planned
  3275.                                       -- for this call...
  3276.         else
  3277.           highest_position := which_buffer.bufcount ;
  3278.           need_to_push     := highest_position + block_size > max_buffer_size ;
  3279.         end if ;
  3280.         if need_to_push then
  3281.           -- we need to push something.
  3282.           if from = thetop then
  3283.             push_data( which_buffer , thebot , temp_successfull ) ;
  3284.           else
  3285.             push_data( which_buffer , thetop , temp_successfull ) ;
  3286.           end if ;
  3287.           -- if temp_successfull then
  3288.             -- text_io.put("Psh");
  3289.           -- else
  3290.             -- text_io.put("NoPsh");
  3291.           -- end if ;
  3292.           if not temp_successfull then
  3293.             successfull := false ;
  3294.             return ;
  3295.           end if ;
  3296.         end if ;
  3297.         -- text_io.put("?");
  3298.         temp_successfull := true ;
  3299.         if from = thetop then
  3300.           -- must pop from the front of the file, and we know something is there
  3301.           -- we have put info out to the file, and it is waiting for us
  3302.           -- here with a block ready to be read and enough room to read it
  3303.           -- put( which_buffer.prestopblock , 4 ) ;
  3304.           getblock( which_buffer , thetop , block_of_data , 
  3305.                     which_buffer.prestopblock , temp_successfull ) ;
  3306.           if temp_successfull then
  3307.             -- now, we actually have the block, too!
  3308.             which_buffer.prestopblock := which_buffer.prestopblock - 1 ;
  3309.             if which_buffer.open_buffer_area then
  3310.               -- we are only working within the first half of the buffer
  3311.               highest_position := which_buffer.first_open_position - 1;
  3312.             else
  3313.               highest_position := which_buffer.bufcount ;
  3314.             end if ;
  3315.             shift_buffer_area( which_buffer , 1 , block_size + 1 , 
  3316.                                highest_position );
  3317.             if which_buffer.open_buffer_area then
  3318.               -- we are popping while the buffer is open.
  3319.               which_buffer.first_open_position 
  3320.                     := which_buffer.first_open_position + block_size ;
  3321.             else
  3322.               -- the buffer is not open
  3323.               which_buffer.bufcount := which_buffer.bufcount + block_size ;
  3324.             end if ;
  3325.             move_block_to_buffer_area ( which_buffer , block_of_data , 1 ) ;
  3326.             adjust_cursors( which_buffer , block_size ) ; 
  3327.           -- else
  3328.             -- put(" HELP>>>>>>>>>>>>>");
  3329.           -- else -- not successfull getting block
  3330.           end if ; -- successfull in reading block ;
  3331.                    -- we had a top block to read
  3332.           -- put("Done");
  3333.         else
  3334.           -- and from = thebot
  3335.           -- must pop from the end of the file
  3336.           if which_buffer.presbotblock > 0 then
  3337.           -- we have put info out to the file, and it is waiting for us
  3338.           -- here with a block ready to be read and enough room to read it
  3339.             getblock( which_buffer , thebot , block_of_data , 
  3340.                       which_buffer.presbotblock , temp_successfull ) ;
  3341.             if temp_successfull then
  3342.               -- now, we actually have the block, too!
  3343.               which_buffer.presbotblock := which_buffer.presbotblock - 1 ;
  3344.               -- for now, we do not call pop_data when the buffer is open
  3345.               -- with a thebot parameter
  3346.               move_block_to_buffer_area ( which_buffer , block_of_data , 
  3347.                                           which_buffer.bufcount + 1 ) ;
  3348.               which_buffer.bufcount := which_buffer.bufcount + block_size ;
  3349.             end if ; -- successfull in reading block ;
  3350.           else
  3351.             -- here if we had no bottom block, but might be in the middle
  3352.             read_new_data ;
  3353.           end if ; -- working a still open input file 
  3354.         end if ; -- reading from the bottom of the file 
  3355.       else
  3356.         temp_successfull := true ; -- because we didn't need to do anything
  3357.       end if   ; -- we had something out there to actually read 
  3358.       -- text_io.put("EndPop");
  3359.       successfull := temp_successfull ;
  3360.     end pop_data ;
  3361.                      
  3362.     procedure interpret_string ( in_string      : in string               ;
  3363.                                  leading_blanks : out type_leading_spaces ;
  3364.                                  first_character: out type_text_length    ;
  3365.                                  last_character : out type_text_length    ;
  3366.                                  length         : out type_line_length  ) is
  3367.                -- Take the input string and interpret it by our rules
  3368.       in_place : integer ;
  3369.       done     : boolean ;
  3370.       blanks   ,
  3371.       first_c  ,
  3372.       last_c   ,
  3373.       len      : integer ;
  3374.       an_error : boolean ;
  3375.       temp_first_character : type_text_length ;
  3376.       temp_last_character  : type_text_length ;
  3377.       temp_length          : type_line_length ;
  3378.     begin -- interpret_string
  3379.       blanks := 0 ;
  3380.       in_place       := 0 ;
  3381.       done           := false ;
  3382.       an_error := false ;
  3383.       while ( in_place < in_string'length )
  3384.       and   ( not done ) loop
  3385.         in_place := in_place + 1 ;
  3386.         case in_string(in_place) is
  3387.           when ' '             => blanks := blanks + 1 ;
  3388.           when ascii.dle       => if in_place < in_string'length then
  3389.                                     in_place := in_place + 1 ;
  3390.                                     if in_string( in_place ) >= ' ' then
  3391.                                       blanks := blanks + 
  3392.                                       character'pos( in_string(in_place) ) -
  3393.                                       character'pos( ' ' ) ;
  3394.                                     end if ;
  3395.                                   end if ;
  3396.           when ascii.ht        => blanks := ( ( blanks / 8 )
  3397.                                                        + 1 ) * 8 ;
  3398.                                   -- 0 .. 7 change to 8
  3399.                                   -- 8 ..15 change to 16
  3400.           when others          => done := true ;
  3401.         end case ;
  3402.       end loop ;
  3403.       -- we are here with in_place set to the last character processed
  3404.       if in_place <= in_string'length then
  3405.         first_c         := in_place ;
  3406.         last_c          := in_string'length ;
  3407.         if done then
  3408.           len           := last_c - in_place + 1 ;
  3409.         else
  3410.           len           := 0 ;
  3411.         end if ;
  3412.       else
  3413.         first_c         := 0 ;
  3414.         last_c          := 0 ;
  3415.         len             := 0 ;
  3416.       end if ;
  3417.       -- Finally, check for errors
  3418.       if blanks <= max_leading_spaces then
  3419.         leading_blanks := blanks ;
  3420.       else
  3421.         leading_blanks := max_leading_spaces ;
  3422.         an_error := true ;
  3423.       end if ;
  3424.       if len <= max_line_length then
  3425.         temp_length := len ;
  3426.       else
  3427.         temp_length := max_line_length ;
  3428.         an_error := true ;
  3429.       end if ;
  3430.       if first_c <= max_column_number then
  3431.         temp_first_character := first_c ;
  3432.       else
  3433.         temp_first_character := max_column_number ;
  3434.         an_error := true ;
  3435.       end if ;
  3436.       if last_c <= max_column_number then
  3437.         temp_last_character := last_c ;
  3438.       else
  3439.         temp_last_character := max_column_number ;
  3440.         an_error := true ;
  3441.       end if ;
  3442.       if an_error then 
  3443.         -- might need to fix last_character
  3444.         if temp_last_character = max_column_number then
  3445.           temp_first_character := temp_last_character - temp_length + 1 ;
  3446.         elsif temp_first_character + temp_length > max_column_number then
  3447.           temp_last_character := max_column_number ;
  3448.           temp_first_character := temp_last_character - temp_length + 1 ;
  3449.         else
  3450.           temp_last_character := temp_first_character + temp_length - 1 ;
  3451.         end if ;
  3452.         error(" Input line has too many spaces or characters." ,
  3453.               not_fatal_error , operator_wait , short_beep ) ;
  3454.       end if ;
  3455.       first_character := temp_first_character ;
  3456.       last_character  := temp_last_character  ;
  3457.       length          := temp_length          ;
  3458.     end interpret_string ;
  3459.       
  3460.     procedure read_next_line ( which_buffer : in out an_editor_buffer ;
  3461.                                env_code     : in out integer      ) is
  3462.                -- Read the next line into an open buffer
  3463.       input_string       : string ( 1 .. max_column_number ) ;
  3464.       new_string_len     : integer ;
  3465.       leading_blanks     : type_leading_spaces ;
  3466.       first_char         ,
  3467.       last_char          : type_text_length ;
  3468.       length             : type_line_length ;
  3469.       ln_start           : type_buffer_position ;
  3470.       old_env_code       : integer          ;
  3471.     begin -- read_next_line
  3472.       text_io.get_line(which_buffer.inputfile,input_string,new_string_len);
  3473.       if ( not text_io.end_of_file(which_buffer.inputfile) )
  3474.       or else ( new_string_len > 0 ) then
  3475.         if env_code >= 0 then
  3476.           -- we must check for an environment line 
  3477.           old_env_code := env_code ;
  3478.           if new_string_len > 0 then
  3479.             convert_string_to_header( input_string(1..new_string_len) ,
  3480.                                         env_code , which_buffer.pagezero ,
  3481.                                         which_buffer );
  3482.             if env_code > 0 then
  3483.               new_string_len := 0 ;
  3484.             end if ;
  3485.           else
  3486.             env_code := -1 ;
  3487.           end if ;
  3488.           if ( old_env_code = 0 ) and then ( env_code < 0 ) then
  3489.             -- no environment found, look for user's environment
  3490.             users_default_header(which_buffer.pagezero) ;
  3491.           end if ;
  3492.         end if ;
  3493.         if env_code < 0 then
  3494.           -- we must work the string because it was not an env string
  3495.           interpret_string(input_string(1..new_string_len),
  3496.                            leading_blanks,first_char,
  3497.                            last_char , length ) ;
  3498.           ln_start := which_buffer.first_open_position ;
  3499.           which_buffer.e_buf(ln_start).data    := extended_character(length) ;
  3500.           which_buffer.e_buf(ln_start+1 ).data :=
  3501.                                           extended_character(leading_blanks) ;
  3502.           for place in 1 .. length loop
  3503.             which_buffer.e_buf(ln_start + 1 + place ).data :=
  3504.               extended_character(
  3505.                   character'pos(input_string( first_char + place - 1 ) ));
  3506.           end loop ;
  3507.           which_buffer.e_buf(ln_start + length + 2 ).data :=
  3508.                                                   extended_character(length) ;
  3509.           which_buffer.first_open_position
  3510.               := which_buffer.first_open_position + length + 3  ;
  3511.           for place in ln_start .. ln_start + length + 2 loop
  3512.             which_buffer.e_buf(place).attr := no_screen_attribute ;
  3513.           end loop ;
  3514.         end if ;
  3515.       else
  3516.         -- empty line.....
  3517.         if env_code = 0 then
  3518.           -- empty file 
  3519.           -- no data anywhere
  3520.           users_default_header(which_buffer.pagezero) ;
  3521.           env_code := -1 ;
  3522.         end if ;
  3523.       end if ;
  3524.       if text_io.end_of_file(which_buffer.inputfile) then
  3525.         if new_string_len = 0 then
  3526.           -- need to adjust the buffer 
  3527.           -- end_of_file with no data on last line
  3528.           -- Put in blank line area for working then...
  3529.           -- which is <0><0><0>
  3530.           for posn in which_buffer.last_open_position - 2 ..
  3531.                       which_buffer.last_open_position loop
  3532.             which_buffer.e_buf(posn) := 
  3533.                           ( extended_character(0) , no_screen_attribute ) ;
  3534.           end loop ;
  3535.           which_buffer.last_open_position:=which_buffer.last_open_position - 3;
  3536.         end if ;
  3537.         which_buffer.still_reading_input_file := false ;
  3538.         text_io.close(which_buffer.inputfile);
  3539.       end if;
  3540.     exception
  3541.       when end_error => -- this is for a telesoft bug....
  3542.                         for posn in which_buffer.last_open_position - 2 ..
  3543.                                     which_buffer.last_open_position loop
  3544.                           which_buffer.e_buf(posn) := 
  3545.                                ( extended_character(0) , no_screen_attribute ) ;
  3546.                         end loop ;
  3547.                         which_buffer.last_open_position 
  3548.                                          := which_buffer.last_open_position - 3;
  3549.                         which_buffer.still_reading_input_file := false ;
  3550.                         text_io.close(which_buffer.inputfile);
  3551.     end read_next_line ;
  3552.  
  3553.   begin -- buffer_general
  3554.     -- BUFFERGN by SAIC/Clearwater General Buffer Routines     23 Jan 85
  3555.     null ;
  3556.   end buffer_general ;
  3557.     
  3558.     use  buffer_general ;
  3559.      
  3560.   package body buffer_lines is 
  3561.     
  3562.     --  Text Buffer Layout Description...
  3563.     --  
  3564.     --  The text buffer has a very special format.  If corrupted, it 
  3565.     --  can become impossible for the editor to recover.  Therefore, 
  3566.     --  text buffer manipulation should NOT be attempted by any routines
  3567.     --  other than those currently sitting in the buffer package.  
  3568.     --
  3569.     --  The text buffer is an array ( 1 .. max_buffer_size ) which 
  3570.     --  contains the following when initialized:
  3571.     --
  3572.     --    <255>                Buffer Start Flag
  3573.     --    <0><0><0>            Line Length / No Leading Spaces / Line Length
  3574.     --    <255>                Buffer End Flag
  3575.     --
  3576.     --
  3577.     --  <Prior Editing Buffer>         Pointed to by prior_buffer_number
  3578.     --  <Top File>                     Blocks of text saved on disk
  3579.     --  <E_buf>                        Text which can be manipulated
  3580.     --  <Bottom File>                  Blocks of text saved on disk
  3581.     --  <Input File>                   Input Text not yet read
  3582.     --  <Following Editing Buffer>     Pointed to by following_buffer_number
  3583.     --
  3584.           
  3585.     function Line_Length ( which_buffer    : in an_editor_buffer     ;
  3586.                            starting_pos    : in type_buffer_position )
  3587.                            return type_line_length is
  3588.       -- Return the line length of the line starting here
  3589.     begin -- line_length 
  3590.       return type_line_length( which_buffer.e_buf(starting_pos).data ) ;
  3591.     end line_length ;
  3592.           
  3593.     function Num_Leading_Spaces ( which_buffer    : in an_editor_buffer     ;
  3594.                               starting_pos    : in type_buffer_position )
  3595.                               return type_leading_spaces is
  3596.       -- Return the leading spaces on the line starting here
  3597.     begin -- num_leading_spaces 
  3598.       return type_leading_spaces( which_buffer.e_buf( starting_pos + 1 )
  3599.                                   .data ) ;
  3600.     end num_leading_spaces ;
  3601.        
  3602.     function num_leading_spaces( which_buffer : in an_editor_buffer ;
  3603.                              a_cursor     : in cursor_position )
  3604.                              return type_leading_spaces is
  3605.       -- Return leading spaces on the cursor line
  3606.     begin -- num_leading_spaces 
  3607.       return type_leading_spaces(which_buffer.e_buf(a_cursor.line_start + 1)
  3608.                                  .data );
  3609.     end num_leading_spaces ;
  3610.           
  3611.     procedure get_line_info( which_buffer     : in an_editor_buffer      ;
  3612.                              starting_position: in type_buffer_position  ;
  3613.                              leading_spaces   : out type_leading_spaces  ;
  3614.                              first_text_position,
  3615.                              last_text_position:out type_buffer_position ;
  3616.                              length    : out Type_Line_Length   ) is
  3617.                --  The buffer and a pointer to the current line's starting
  3618.                --  position are provided.  Note that this starting position
  3619.                --  is a pointer to the starting line length for the line.
  3620.                --  The number of leading spaces and pointers to the first
  3621.                --  and last characters on the line are returned.  Also, 
  3622.                --  the count of the number of characters is provided.
  3623.       temp_length : type_line_length ;
  3624.     begin
  3625.       temp_length := line_length(which_buffer,starting_position);
  3626.         -- the length of the current line is at the current position
  3627.       if temp_length = buffer_boundry then
  3628.         -- we are sitting at the starting or ending boundry
  3629.         leading_spaces      := 0 ;
  3630.         first_text_position := 0 ;
  3631.         last_text_position  := 0 ;
  3632.         length              := 0 ;
  3633.       else
  3634.         leading_spaces := Num_leading_spaces(which_buffer,starting_position);
  3635.         first_text_position := starting_position + 2 ;
  3636.         last_text_position  := starting_position + temp_length + 1 ;
  3637.         length := temp_length ;
  3638.       end if ;
  3639.     end get_line_info ;
  3640.           
  3641.     procedure ot_line( which_buffer : in an_editor_buffer      ;
  3642.                        line         : in window_line_number  ;
  3643.                        column       : in window_column_number ;
  3644.                        first_text   ,
  3645.                        last_text    : in type_buffer_position ) is
  3646.                --  The buffer is provided, as well as the line
  3647.                --  and column to start with when displaying text.
  3648.                --  the actual text exists from first_text to 
  3649.                --  last_text in the buffer.  Output it IF it fits
  3650.                --  within the current editor window.
  3651.       final_first_text: type_buffer_position ;
  3652.       final_last_text : type_buffer_position ;
  3653.       final_column    : window_column_number ;
  3654.       last_possible_line : window_line_number := window_height(which_buffer);
  3655.       first_possible_col : window_column_number:=lowest_column_number
  3656.                                                               (which_buffer);
  3657.       last_possible_col  : window_column_number:=highest_column_number
  3658.                                                               (which_buffer);
  3659.     begin
  3660.       if line > last_possible_line then
  3661.         null  ;  -- we are past the end of the window.
  3662.       elsif column > last_possible_col then
  3663.         -- we are past the right edge of the screen
  3664.         if line = 0 then
  3665.           -- we must be at the first text position on the last line 
  3666.           goto_line_column ( which_buffer , last_possible_line ,
  3667.                                             last_possible_col ) ;
  3668.         else
  3669.           goto_line_column( which_buffer , line , last_possible_col ) ;
  3670.         end if ;
  3671.         set_reverse( which_buffer.e_buf( first_text ).attr = inverse_video ) ;
  3672.         put('!');
  3673.       else
  3674.         -- Now, check to skip leading characters if columns_over /= 0
  3675.         if column < first_possible_col then
  3676.           -- some leading text will have to go.
  3677.           final_first_text := first_text + first_possible_col - column ;
  3678.           final_column     := first_possible_col ;
  3679.           if final_first_text > last_text then
  3680.             goto_line_column( which_buffer , line , first_possible_col ) ;
  3681.             put('!');
  3682.             return;
  3683.           end if;
  3684.         else
  3685.           final_first_text := first_text ;
  3686.           final_column := column ;
  3687.         end if ;
  3688.         -- Now check to truncate the line because it is too long.
  3689.         if ( line = last_possible_line ) 
  3690.         or ( line = 0 )  then
  3691.           -- line as zero means do whatever line we are on...
  3692.           last_possible_col := last_possible_col - 1 ;
  3693.         end if ;
  3694.         if final_column + last_text - final_first_text > last_possible_col then
  3695.           final_last_text := final_first_text + last_possible_col 
  3696.                                               - final_column - 1 ;
  3697.           -- Minus 1 because we will put a '!' out there
  3698.         else
  3699.           final_last_text := last_text ;
  3700.         end if ;
  3701.         if line = 0 then
  3702.           goto_line_column( which_buffer , last_possible_line , final_column);
  3703.         else
  3704.           goto_line_column( which_buffer , line , final_column );
  3705.         end if ;
  3706.         for text_pos in final_first_text .. final_last_text loop
  3707.           put( which_buffer.e_buf( text_pos ) );
  3708.         end loop;
  3709.         if last_text /= final_last_text then
  3710.           put('!');
  3711.         end if;
  3712.       end if;
  3713.     end ot_line ;
  3714.         
  3715.     procedure ot_line( which_buffer : in an_editor_buffer      ;
  3716.                        line         : in window_line_number  ;
  3717.                        column       : in window_column_number;
  3718.                        Line_Of_Text : in type_text_line        ) is
  3719.                --  The buffer is provided, as well as the line
  3720.                --  and column to start with when displaying text.
  3721.                --  the actual text exists in Line_Of_Text
  3722.                --  Output it IF it fits within the current editor window.
  3723.                --  Note that we will have to skip the first 
  3724.                --  spaces (designated by leading_spaces) because they
  3725.                --  are already included in the starting screen position
  3726.       first_text       : type_text_length ;
  3727.       last_text        : type_text_length ;
  3728.       final_last_text  : type_text_length ;
  3729.       final_column     : window_column_number ;
  3730.     begin -- ot_line
  3731.       set_reverse(false);
  3732.       if line > window_height(which_buffer) then
  3733.         null  ;  -- we are past the end of the window.
  3734.       elsif column > highest_column_number(which_buffer) then
  3735.         -- we are past the right edge of the screen
  3736.         if line = 0 then
  3737.           goto_line_column ( which_buffer , window_height(which_buffer),
  3738.                           highest_column_number(which_buffer) ) ;
  3739.         else
  3740.           goto_line_column( which_buffer , line , 
  3741.                           highest_column_number(which_buffer) ) ;
  3742.         end if ;
  3743.         put('!');
  3744.       else
  3745.         first_text := line_of_text.leading_spaces + 1 ;
  3746.         last_text  := line_of_text.data_length        ;
  3747.         -- Now, check to skip leading characters if columns_over /= 0
  3748.         if column < lowest_column_number(which_buffer) then
  3749.           -- some leading text will have to go.
  3750.           first_text := first_text 
  3751.                         + lowest_column_number(which_buffer) - column ;
  3752.           final_column := lowest_column_number(which_buffer) ;
  3753.           if first_text > last_text then
  3754.             return;
  3755.           end if;
  3756.         else
  3757.           final_column := column ;
  3758.         end if ;
  3759.         -- Now check to truncate the line because it is too long.
  3760.         if final_column + last_text - first_text 
  3761.                     > highest_column_number(which_buffer) then
  3762.           final_last_text := first_text + highest_column_number(which_buffer)
  3763.                                         - final_column - 1 ;
  3764.           -- Minus 1 because we will put a '!' out there
  3765.         else
  3766.           final_last_text := last_text ;
  3767.         end if ;
  3768.         if line = 0 then
  3769.           goto_line_column( which_buffer , window_height(which_buffer) ,
  3770.                                                            final_column );
  3771.         else
  3772.           goto_line_column( which_buffer , line , final_column );
  3773.         end if ;
  3774.         for text_pos in first_text .. final_last_text loop
  3775.           put( character'val(line_of_text.data(text_pos)) ) ;
  3776.         end loop;
  3777.         if last_text /= final_last_text then
  3778.           put('!');
  3779.         end if;
  3780.       end if;
  3781.     end ot_line ;
  3782.         
  3783.     procedure get_text_line( which_buffer     : in an_editor_buffer      ;
  3784.                              starting_position: in type_buffer_position  ;
  3785.                              Line_Of_Text     : out type_text_line       ) is
  3786.                --  The buffer and a pointer to the current line's starting
  3787.                --  position are provided.  Note that this starting position
  3788.                --  is an entity which cannot be manipulated by the caller
  3789.                --  The number of leading spaces , the length of the text
  3790.                --  in the line, and the actual text line are returned.
  3791.                --  Note that the line_of_text.data actually includes the
  3792.                --  leading_spaces leading spaces.
  3793.       spaces : type_leading_spaces ;
  3794.       length   : type_line_length ;
  3795.       first_text_position,
  3796.       last_text_position : type_buffer_position ;
  3797.       temp_line_of_text  : type_text_line ;
  3798.     begin
  3799.       length := line_length(which_buffer,starting_position);
  3800.         -- the length of the current line is at the current position
  3801.       if length = buffer_boundry then
  3802.         -- we are sitting at the starting or ending boundry
  3803.         temp_line_of_text.leading_spaces  := 0 ;
  3804.         temp_line_of_text.data_length     := 0 ;
  3805.       else
  3806.         spaces := num_leading_spaces(which_buffer,starting_position);
  3807.         temp_line_of_text.leading_spaces := spaces ;
  3808.         temp_line_of_text.data_length    := length + 
  3809.                                             temp_line_of_text.leading_spaces ;
  3810.         if spaces > 0 then
  3811.           for a_space in 1 .. spaces loop         
  3812.             temp_line_of_text.data(a_space):=
  3813.                                   extended_character(character'pos(' ')) ;
  3814.           end loop ;
  3815.         end if ;
  3816.         if length > 0 then
  3817.           for character_pos in 1 .. length loop
  3818.             temp_line_of_text.data( spaces + character_pos )
  3819.                 := which_buffer.e_buf( starting_position + 1 + character_pos ) 
  3820.                    .data ;
  3821.           end loop ;
  3822.         end if;
  3823.       end if ;
  3824.       line_of_text := temp_line_of_text ;
  3825.     end get_text_line ;
  3826.          
  3827.     procedure show_line( which_buffer         : in an_editor_buffer      ;
  3828.                          starting_position    : in type_buffer_position  ;
  3829.                          line_number_within_file : in Line_Number        ;
  3830.                          move_to_starting_pos : in boolean := true       ) is
  3831.                --  The buffer and a pointer to the current line's starting
  3832.                --  position are provided.  Also, the actual line number
  3833.                --  within the file is sent.  This routine sends the text
  3834.                --  line to the screen.
  3835.       spaces           : type_leading_spaces  ;
  3836.       first_text       : type_buffer_position ;
  3837.       last_text        : type_buffer_position ;
  3838.       length           : Type_line_Length ;
  3839.       window_line      : window_line_number ;
  3840.     begin
  3841.       get_line_info(which_buffer,starting_position,spaces,first_text,
  3842.                     last_text,length);
  3843.       if first_text = 0 then   -- No text
  3844.         return ;               --         so we don't do anything.
  3845.       end if;
  3846.       -- We get here with spaces, first_text, and last_text set
  3847.       if move_to_starting_pos then 
  3848.         window_line := line_number_within_file 
  3849.                        - which_buffer.top_screen_cursor.file_line_number + 1 ;
  3850.         ot_line(which_buffer,window_line, spaces + 1 ,first_text,last_text);
  3851.       else
  3852.         ot_line( which_buffer , 0 , spaces + 1 , first_text , last_text );
  3853.       end if ;
  3854.     end show_line ;
  3855.                      
  3856.     procedure show_line( which_buffer         : in an_editor_buffer      ;
  3857.                          Line_Of_Text         : in type_text_line        ;
  3858.                          line_number_within_file : in Line_Number        ;
  3859.                          move_to_starting_pos : in boolean := true       ) is
  3860.                --  The buffer and the line of text to put on the screen    
  3861.                --  are provided.  Also, the actual line number within the 
  3862.                --  file is sent.  This routine sends the text
  3863.                --  line to the screen.
  3864.       window_line      : window_line_number ;
  3865.     begin
  3866.       if move_to_starting_pos then 
  3867.         window_line := line_number_within_file 
  3868.                        - which_buffer.top_screen_cursor.file_line_number + 1 ;
  3869.         ot_line(which_buffer,window_line, 1 ,line_of_text);
  3870.       else
  3871.         ot_line( which_buffer , 0 , 1 , line_of_text );
  3872.       end if ;
  3873.     end show_line ;
  3874.                      
  3875.     procedure line_forward( which_buffer  : in out an_editor_buffer ) is
  3876.                --  The buffer and starting position of the current line
  3877.                --  are provided.  Returns the starting position of the
  3878.                --  line immediately following the old line.  If the new
  3879.                --  location is the same as the starting position, then
  3880.                --  movement was not possible.
  3881.                --  moves from fixed_cursor.linestart and sets moving_cursor
  3882.       ending_position : type_buffer_position ;
  3883.       successfull     : boolean              ;
  3884.     begin -- line_forward 
  3885.       if which_buffer.open_buffer_area then
  3886.         -- we might hit the end of an open area....
  3887.         which_buffer.e_buf(which_buffer.first_open_position)
  3888.           := ( buffer_boundry , no_screen_attribute ) ;
  3889.       end if ;
  3890.       if which_buffer.fixed_cursor.line_start + max_bytes_in_line
  3891.             >= which_buffer.bufcount - max_bytes_in_line then
  3892.               -- used to subtract screen_size from bufcount (not maxbytes)
  3893.                        -- If the possible starting position of the 
  3894.                        -- next line (which can be the current position
  3895.                        -- plus the maximum number of bytes in a line)
  3896.                        -- is closer to the end of the buffer than a
  3897.                        -- screen size, then bump to the end
  3898.         pop_data( which_buffer , thebot , successfull ) ; 
  3899.                        -- Get data from bottom of file
  3900.         if not successfull then
  3901.           which_buffer.moving_cursor := which_buffer.fixed_cursor ;
  3902.           return ;
  3903.         end if ;
  3904.       end if ;
  3905.       ending_position :=
  3906.                 which_buffer.fixed_cursor.line_start + line_length( 
  3907.                     which_buffer , which_buffer.fixed_cursor.line_start ) + 3 ;
  3908.                        -- Move from the starting position, over the number
  3909.                        -- of text bytes in this line, and then over the
  3910.                        -- current and ending length bytes
  3911.       if which_buffer.e_buf(ending_position).data = buffer_boundry then
  3912.         which_buffer.moving_cursor := which_buffer.fixed_cursor ;
  3913.       else
  3914.         which_buffer.moving_cursor.line_start := ending_position ;
  3915.         which_buffer.moving_cursor.file_line_number :=
  3916.                 which_buffer.fixed_cursor.file_line_number + 1 ;
  3917.         which_buffer.moving_cursor.buffer_position := 0 ;
  3918.         which_buffer.moving_cursor.column_offset   := 0 ;
  3919.       end if;
  3920.     end line_forward ;
  3921.         
  3922.     procedure line_backward(which_buffer  : in out an_editor_buffer   ) is
  3923.                --  The buffer and starting position of the current line
  3924.                --  are provided.  Returns the starting position of the
  3925.                --  line immediately before the old line.  If the new
  3926.                --  location is the same as the starting position, then
  3927.                --  movement was not possible.
  3928.                --  moves from fixed_cursor.linestart and sets moving_cursor
  3929.       successfull     : boolean              ;
  3930.       a_position      : type_buffer_position ;
  3931.     begin -- line_backward 
  3932.       if which_buffer.fixed_cursor.line_start 
  3933.                 < max_bytes_in_line + max_bytes_in_line then
  3934.                        -- screen_size + max_bytes_in_line then
  3935.                        -- If the possible starting position of the 
  3936.                        -- next line (which can be the current position
  3937.                        -- plus the maximum number of bytes in a line)
  3938.                        -- is closer to the end of the buffer than a
  3939.                        -- screen size, then bump to the end
  3940.         pop_data( which_buffer , thetop , successfull ) ; 
  3941.                        -- Get data from bottom of file
  3942.         if not successfull then
  3943.           which_buffer.moving_cursor := which_buffer.fixed_cursor ;
  3944.           return ;
  3945.         end if ;
  3946.       end if ;
  3947.       a_position := which_buffer.fixed_cursor.line_start ;
  3948.       if which_buffer.e_buf(a_position - 1 ).data = buffer_boundry then
  3949.         which_buffer.moving_cursor := which_buffer.fixed_cursor ;
  3950.       else
  3951.         which_buffer.moving_cursor.line_start := a_position
  3952.                          - line_length( which_buffer , a_position-1 ) - 3 ;
  3953.                        -- Move from the starting position, over the number
  3954.                        -- of text bytes in the previous line, and then over
  3955.                        -- the current and ending length bytes
  3956.         which_buffer.moving_cursor.file_line_number :=
  3957.                 which_buffer.fixed_cursor.file_line_number - 1 ;
  3958.         which_buffer.moving_cursor.buffer_position := 0 ;
  3959.         which_buffer.moving_cursor.column_offset   := 0 ;
  3960.       end if ;
  3961.     end line_backward ;
  3962.   
  3963.     function cursor_off_screen ( which_buffer : in an_editor_buffer ) 
  3964.                                         return boolean is
  3965.     begin -- cursor_off_screen
  3966.       if ( which_buffer.top_screen_cursor.line_start = 0 ) then 
  3967.       -- or else ( which_buffer.next_screen_cursor.line_start = 0 ) then 
  3968.         -- we have moved around too much to even find out where we are.
  3969.         -- must completely redraw screen
  3970.         return true ;
  3971.         -- This all depends upon having the right sized buffer!!!!
  3972.       elsif which_buffer.fixed_cursor.column_offset
  3973.                           < lowest_column_number(which_buffer)
  3974.          or which_buffer.fixed_cursor.column_offset
  3975.                           > highest_column_number(which_buffer) then
  3976.         return true ;
  3977.       elsif which_buffer.fixed_cursor.file_line_number 
  3978.                                < which_buffer.top_screen_cursor
  3979.                                         .file_line_number then
  3980.         return true ;
  3981.       elsif which_buffer.fixed_cursor.file_line_number 
  3982.                                >= -- which_buffer.next_screen_cursor
  3983.                                         -- .file_line_number then
  3984.                         which_buffer.top_screen_cursor.file_line_number
  3985.                                         + window_height( which_buffer ) then
  3986.         return true ;
  3987.       else
  3988.         -- ok, here we just need to find out where we are and go there
  3989.         return false ;
  3990.       end if ;
  3991.     end cursor_off_screen ;
  3992.       
  3993.     procedure set_cursor_up_lines ( which_buffer : in out an_editor_buffer ;
  3994.                                     old_cursor   : in cursor_position      ;
  3995.                                     new_cursor   : out cursor_position     ;
  3996.                                     lines_up     : integer               ) is
  3997.       -- cannot change fixed_cursor, even if called to change fixed cursor
  3998.       number_of_lines_moved : integer ;
  3999.     begin -- set_cursor_up_lines
  4000.       number_of_lines_moved := 0 ;
  4001.       which_buffer.floating_cursor := which_buffer.fixed_cursor ;
  4002.       which_buffer.fixed_cursor := old_cursor ;
  4003.       while number_of_lines_moved < lines_up loop
  4004.         -- we need to go backwards, and we know that we can without error
  4005.         line_backward(which_buffer);
  4006.       exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ;
  4007.         which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  4008.         number_of_lines_moved := number_of_lines_moved + 1 ;
  4009.       end loop ;
  4010.       new_cursor := which_buffer.fixed_cursor ;
  4011.       which_buffer.fixed_cursor := which_buffer.floating_cursor ;
  4012.     end set_cursor_up_lines ;
  4013.   
  4014.     procedure set_cursor_down_lines(which_buffer : in out an_editor_buffer ;
  4015.                                     old_cursor   : in cursor_position      ;
  4016.                                     new_cursor   : out cursor_position     ;
  4017.                                     lines_down   : integer               ) is
  4018.       number_of_lines_moved : integer ;
  4019.       -- cannot change fixed_cursor, even if called to change fixed cursor
  4020.     begin -- set_cursor_down_lines
  4021.       number_of_lines_moved := 0 ;
  4022.       which_buffer.floating_cursor := which_buffer.fixed_cursor ;
  4023.       which_buffer.fixed_cursor := old_cursor ;
  4024.       while number_of_lines_moved < lines_down loop
  4025.         -- we need to go backwards, and we know that we can without error
  4026.         line_forward(which_buffer);
  4027.       exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ;
  4028.         which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  4029.         number_of_lines_moved := number_of_lines_moved + 1 ;
  4030.       end loop ;
  4031.       new_cursor := which_buffer.fixed_cursor ;
  4032.       which_buffer.fixed_cursor := which_buffer.floating_cursor ;
  4033.     end set_cursor_down_lines ;
  4034.   
  4035.     procedure put_cursor_on_line ( which_buffer : in out an_editor_buffer ;
  4036.                                    this_line : in window_line_number ) is
  4037.       -- set the first line position so as to make the cursor on
  4038.       -- the this_line line
  4039.       target_line_number : line_number ;
  4040.     begin -- put_cursor_on_line
  4041.       -- show_buffer( 'V' ) ;
  4042.       set_cursor_up_lines ( which_buffer , which_buffer.fixed_cursor      ,
  4043.                                            which_buffer.top_screen_cursor ,
  4044.                                            this_line - 1 ) ;
  4045.       -- show_buffer( 'V' ) ;
  4046.       target_line_number := which_buffer.top_screen_cursor.file_line_number
  4047.                              + window_height( which_buffer ) ;
  4048.       set_cursor_down_lines ( which_buffer,which_buffer.fixed_cursor      ,
  4049.                                            which_buffer.next_screen_cursor,
  4050.                                            target_line_number -
  4051.                                            which_buffer.fixed_cursor   .
  4052.                                              file_line_number ) ;
  4053.       if which_buffer.top_screen_cursor.file_line_number 
  4054.           + window_height( which_buffer ) /= which_buffer.next_screen_cursor
  4055.                                                 . file_line_number then
  4056.         which_buffer.next_screen_cursor.line_start := 0 ;
  4057.         which_buffer.next_screen_cursor.file_line_number :=
  4058.           which_buffer.next_screen_cursor.file_line_number + 1 ; 
  4059.           -- above statement added 14 Mar 85
  4060.       end if ;
  4061.       -- show_buffer( 'V' ) ;
  4062.     end put_cursor_on_line ;
  4063.         
  4064.     procedure memory_center ( which_buffer : in out an_editor_buffer ;
  4065.                               new_line_number : in window_line_number:=0) is
  4066.       -- center the buffer's cursor in memory so that we can place the
  4067.       -- cursor anywhere on the screen and feel safe that we will not run
  4068.       -- out of text in memory
  4069.       --
  4070.       -- We enter with cursor completely defined ( except buffer_position
  4071.       --                which can be 0 if it is not in the current line's
  4072.       --                text area.
  4073.       -- Also, first_window_line_position & first_window_line might not
  4074.       -- even be defined (if we have moved around a lot).  In that case,
  4075.       -- first_window_line_position is 0 .
  4076.         
  4077.       -- This routine guarantees us that we can move one line in either
  4078.       -- direction off of the screen if there is any text there.
  4079.         
  4080.       moved_cursor     : cursor_position ;
  4081.         
  4082.       count_backward     : integer ;
  4083.       
  4084.     begin -- memory_center 
  4085.       -- show_buffer('V');
  4086.       if which_buffer.fixed_cursor.line_start 
  4087.                   < screen_size + max_bytes_in_line then
  4088.         -- the +max bytes ensures that we have one extra line available
  4089.         -- we might have to do some work to make sure we can be at the
  4090.         -- last line on the screen
  4091.         set_cursor_up_lines ( which_buffer , which_buffer.fixed_cursor      ,
  4092.                                              moved_cursor , 
  4093.                                              window_height( which_buffer ) ) ;
  4094.         count_backward := which_buffer.fixed_cursor.file_line_number
  4095.                                 - moved_cursor.file_line_number ;
  4096.       else
  4097.         count_backward := window_height( which_buffer ) ;
  4098.         -- to say that we have more than a window in that direction
  4099.       end if ;
  4100.       -- Now, we need to set top_screen_cursor & next_screen_cursor 
  4101.       -- we might need to completely refigure the window position
  4102.       -- count_backward tells us how many lines we can move backwards
  4103.       -- if new_line_number is > 0 then it is telling us where to put it
  4104.       if new_line_number > 0 then
  4105.         -- new line number is the line number on the screen where the caller
  4106.         -- wants the cursor to end up
  4107.         if new_line_number > window_height( which_buffer ) then
  4108.           -- they tried to put us off the screen...
  4109.           if count_backward + 1 > window_height( which_buffer ) then
  4110.             put_cursor_on_line( which_buffer ,window_height ( which_buffer ) ) ;
  4111.           else
  4112.             put_cursor_on_line( which_buffer , count_backward + 1 ) ;
  4113.           end if ;
  4114.         elsif new_line_number > count_backward + 1 then
  4115.           -- by definition, count_backward + 1 must be less than
  4116.           -- the window_height, otherwise, the previous if would have 
  4117.           -- caught it
  4118.           put_cursor_on_line( which_buffer , count_backward + 1 ) ;
  4119.         else
  4120.           put_cursor_on_line( which_buffer , new_line_number ) ;
  4121.         end if ;
  4122.       elsif which_buffer.top_screen_cursor.line_start = 0 then
  4123.         -- we have to refigure because we are lost
  4124.         if count_backward + 1 <= window_height( which_buffer ) then
  4125.           -- we are on the first screen....
  4126.           put_cursor_on_line(which_buffer,
  4127.                              which_buffer.fixed_cursor.file_line_number ) ;
  4128.         -- elsif count_forward + 1 <= window_height( which_buffer ) then
  4129.           -- we are on the last screen....
  4130.           -- put_cursor_on_line( which_buffer,window_height ( which_buffer ) ) ;
  4131.         else
  4132.           -- we are on a middle screen
  4133.           put_cursor_on_line( which_buffer , 
  4134.                               window_height ( which_buffer ) / 2 ) ;
  4135.         end if ;
  4136.       else
  4137.         -- we get here if we are off the screen but still 
  4138.         -- know what the first window line position is 
  4139.         null ; -- handled by the caller....
  4140.       end if ;
  4141.       -- show_buffer('V');
  4142.     end memory_center ;
  4143.         
  4144.   begin -- buffer_lines
  4145.     -- BUFFERMS by SAIC/Clearwater General Buffer Routines     24 Jan 85
  4146.     null ;
  4147.   end buffer_lines ;
  4148.      
  4149.     use  buffer_lines   ;
  4150.    
  4151.     procedure re_initialize ( which_buffer : in out an_editor_buffer ) is
  4152.       -- Do the initialization which is also done each time a buffer
  4153.       -- is re_loaded
  4154.     begin -- re_initialize 
  4155.       which_buffer.e_buf(0).data       := extended_character(buffer_boundry)  ;
  4156.       which_buffer.e_buf(1).data       := extended_character(  0)     ;
  4157.       which_buffer.e_buf(2).data       := extended_character(  0)     ;
  4158.       which_buffer.e_buf(3).data       := extended_character(  0)     ;
  4159.       which_buffer.e_buf(4).data       := extended_character(buffer_boundry)  ;
  4160.       which_buffer.fixed_cursor.buffer_position        := 0     ;
  4161.       which_buffer.fixed_cursor.file_line_number       := 1     ;
  4162.       which_buffer.fixed_cursor.line_start             := 1     ;
  4163.       which_buffer.fixed_cursor.column_offset          := 0     ;
  4164.       which_buffer.floating_cursor     := which_buffer.fixed_cursor ;
  4165.       which_buffer.moving_cursor       := which_buffer.fixed_cursor ;
  4166.       which_buffer.top_screen_cursor   := which_buffer.fixed_cursor ;
  4167.       which_buffer.next_screen_cursor  := which_buffer.fixed_cursor ;
  4168.       which_buffer.bufcount                 :=        4      ;
  4169.       which_buffer.still_reading_input_file :=   false       ;
  4170.       which_buffer.copy_file_name           := blank_file_name ;
  4171.       which_buffer.output_file_name         := blank_file_name ;
  4172.       which_buffer.prestopblock             :=        0      ;
  4173.       which_buffer.presbotblock             :=        0      ;
  4174.       -- Buffer does not need initialization
  4175.       which_buffer.pagezero                 := default_header ;
  4176.       which_buffer.open_buffer_area         :=    false      ;
  4177.       which_buffer.first_open_position      :=        0      ;
  4178.       which_buffer.last_open_position       :=        0      ;
  4179.       -- new_marker( which_buffer.saved_cursor ) ;
  4180.       new_marker( which_buffer.last_marked_position ) ;
  4181.     end re_initialize ;
  4182.      
  4183.     procedure initialize_buffer( which_buffer : out an_editor_buffer ;
  4184.                                  buffer_number: in a_buffer_number   ) is
  4185.                -- Initialize the buffer.
  4186.       temp_which_buffer : an_editor_buffer ;
  4187.       successfull : boolean ;
  4188.     begin -- initialize_buffer 
  4189.       temp_which_buffer := new real_editor_buffer ;
  4190.       temp_which_buffer.window                   := no_window     ;
  4191.       temp_which_buffer.buffer_number            := buffer_number ;
  4192.       create( temp_which_buffer , thetop , successfull ) ;
  4193.       if successfull then
  4194.         -- If we create any temporary files, we need to have buffer_list
  4195.         -- set so that an exception can generate a request to close
  4196.         -- any created files
  4197.         buffer_list(buffer_number) := temp_which_buffer ;
  4198.         create( temp_which_buffer , thebot , successfull ) ;
  4199.         if successfull then
  4200.           temp_which_buffer.input_file_name          := blank_file_name ;
  4201.           temp_which_buffer.prior_buffer             :=     null      ;
  4202.           temp_which_buffer.following_buffer         :=     null      ;
  4203.           temp_which_buffer.name                     := "BufferName"  ;
  4204.           temp_which_buffer.mode                     :=   insert      ;
  4205.           if text_io.is_open(temp_which_buffer.inputfile) then
  4206.             text_io.close(temp_which_buffer.inputfile);
  4207.           end if ;
  4208.           re_initialize(temp_which_buffer);
  4209.              -- The buffer number is used to keep track of each buffer
  4210.              -- The (buffer_boundry) signifies the start of the real text area
  4211.              -- The (0)   is the preceding Line Length
  4212.              -- The next (0) is the following Line Length
  4213.              -- The final (buffer_boundry) is the end of buffer signal
  4214.              -- We are at position 1, which is the start of line 1
  4215.              -- We are in line 1
  4216.              -- Line 1 starts at position 1
  4217.              -- We are not offset into the line yet
  4218.              -- We are at the left edge of our window
  4219.              -- The highest numbered extended_character in the e_buf is #3
  4220.              -- We do Not yet have any data from an input file 
  4221.         end if ;
  4222.       end if ;
  4223.       if not successfull then
  4224.         -- we have a fatal error.  
  4225.         error( "Unable To Open Temporary Editor Files.",
  4226.                fatal_error , operator_wait , long_beep ) ;
  4227.       end if ;
  4228.       which_buffer := temp_which_buffer ;
  4229.     end initialize_buffer ;
  4230.                   
  4231.     procedure load_file( which_buffer : in out an_editor_buffer ;
  4232.                          file_to_load : in ascii_text_file_name ) is
  4233.                -- Load the named file into the buffer.  We can assume
  4234.                -- an empty buffer in this case.
  4235.       bytes_needed_for_load : constant integer := screen_size + screen_size ;
  4236.         -- we must load at least two screens of data
  4237.       input_string       : string ( 1 .. max_column_number ) ;
  4238.       new_string_len     : integer ;
  4239.       leading_blanks     : type_leading_spaces ;
  4240.       first_char         ,
  4241.       last_char          : type_text_length ;
  4242.       length             : type_text_length ;
  4243.       ln_start           : type_buffer_position ;
  4244.       env_code , 
  4245.       old_env_code       : integer ;
  4246.       ok                 : boolean ;
  4247.       file_loaded        : ascii_text_file_name ;
  4248.     begin -- load_file
  4249.       file_loaded := file_to_load ;
  4250.       open_for_read(which_buffer.inputfile,file_loaded ,ok);
  4251.       if not ok then
  4252.         -- File not found, even though the caller assured us that it would
  4253.         -- really exist.
  4254.         error("Bad Input File Name.",
  4255.                not_fatal_error , operator_wait , medium_beep ) ;
  4256.       else
  4257.         -- OK!
  4258.         which_buffer.input_file_name := file_loaded  ;
  4259.         re_initialize(which_buffer);  -- reset as empty buffer
  4260.         which_buffer.still_reading_input_file := true ;
  4261.         open_buffer(which_buffer,which_buffer.fixed_cursor.line_start,
  4262.                        bytes_needed_for_load );
  4263.           -- Open up a text area here so that we can insert the file
  4264.         -- Now, since we are reading a file, kill the empty line in buffer
  4265.         which_buffer.last_open_position := which_buffer.last_open_position + 3;
  4266.         env_code := 0 ; -- no environment lines read yet 
  4267.         loop
  4268.           read_next_line( which_buffer , env_code ) ;
  4269.         exit when not which_buffer.still_reading_input_file 
  4270.                or which_buffer.first_open_position + minimum_open_area
  4271.                      > which_buffer.last_open_position ;
  4272.         end loop ;
  4273.           -- Data loaded
  4274.         close_buffer(which_buffer);
  4275.         memory_center ( which_buffer , 1 ) ; -- place the cursor on line 1
  4276.         -- Finally, fix the cursor position 
  4277.         which_buffer.fixed_cursor.column_offset      :=
  4278.                num_leading_spaces(which_buffer,which_buffer.fixed_cursor) + 1 ;
  4279.         which_buffer.moving_cursor.column_offset      :=
  4280.                num_leading_spaces(which_buffer,which_buffer.moving_cursor) + 1 ;
  4281.       end if ; -- we actually had a file out there 
  4282.     end load_file ;
  4283.  
  4284.     procedure copy_file( which_buffer : in out an_editor_buffer ;
  4285.                          file_to_copy : in ascii_text_file_name ;
  4286.                          first_marker : in str10 ;
  4287.                          last_marker  : in str10 ) is
  4288.                -- Copy the named file in at the current position in 
  4289.                -- which buffer.
  4290.       bytes_needed_for_load : constant integer := screen_size + screen_size ;
  4291.         -- we must load at least two screens of data
  4292.       new_string_length  : integer ;
  4293.       leading_blanks     : type_leading_spaces ;
  4294.       first_char         ,
  4295.       last_char          : type_text_length ;
  4296.       length             : type_line_length ;
  4297.       ln_start           : type_buffer_position ;
  4298.       copy_string          : string ( 1 .. max_column_number ) ;
  4299.       lines_added          : integer ;
  4300.       original_line_number : integer ;
  4301.       copyfile             : text_file_type ;
  4302.       successfull          : boolean        ;
  4303.       env_code , 
  4304.       old_env_code       : integer ;
  4305.       copy_header        : header           ;
  4306.       ok                 : boolean          ;
  4307.       file_copied        : ascii_text_file_name ;
  4308.       first_line_to_move_in : integer := 1 ;
  4309.       last_line_to_move_in  : integer := integer'last ;
  4310.       first_col_to_move_in : integer := 1 ;
  4311.       last_col_to_move_in  : integer := integer'last ;
  4312.       current_line_reading  : integer := 1 ;
  4313.       
  4314.       procedure adjust_markers ( start_line : line_number ;
  4315.                                  start_column : column_position ;
  4316.                                  end_line     : line_number     ;
  4317.                                  end_column   : column_position ) is
  4318.         new_text_range : text_range ;
  4319.           
  4320.       begin -- adjust_markers 
  4321.         new_text_range.lo_position := ( start_line , start_column ,
  4322.                                         no_screen_attribute , which_buffer ) ;
  4323.         new_text_range.hi_position := ( end_line   , end_column   ,
  4324.                                         no_screen_attribute , which_buffer ) ;
  4325.         new_text_range.attribute   := no_screen_attribute ;
  4326.         update_markers_for_added_text( which_buffer , new_text_range ) ;
  4327.       end adjust_markers ;
  4328.         
  4329.       procedure merge_environment ( old_environment : in out header ;
  4330.                                     new_environment : in     header ) is
  4331.       begin -- merge_environment 
  4332.         -- Later we might want to merge in unique marker names
  4333.         null ;
  4334.       end merge_environment ;
  4335.         
  4336.       procedure empty_environment ( old_environment : in out header ) is
  4337.       begin -- empty_environment 
  4338.         -- and then delete the old markers.....
  4339.         for posn in 1 .. old_environment.marker_count loop
  4340.           dispose( old_environment.markers( posn ) .location ) ;
  4341.         end loop ;
  4342.       end empty_environment ;
  4343.         
  4344.       function find_marker ( name : in str10 ) return marker_number is
  4345.       begin -- find_marker
  4346.         for posn in 1 .. copy_header.marker_count loop
  4347.           if name = copy_header.markers ( posn ) . name then
  4348.             return posn ;
  4349.           end if ;
  4350.         end loop ;
  4351.         return 0 ;
  4352.       end find_marker ;
  4353.      
  4354.       function work_environment return boolean is
  4355.         -- return true if we successfull moved past environment
  4356.         ok : boolean := true ;
  4357.         mark_place : integer ;
  4358.       begin -- work_environment
  4359.         env_code := 0 ; -- no environment lines read yet 
  4360.         loop
  4361.         exit when text_io.end_of_file(copyfile);
  4362.           text_io.get_line(copyfile,copy_string,new_string_length);
  4363.         exit when text_io.end_of_file(copyfile) and new_string_length = 0 ;
  4364.           if env_code >= 0 then
  4365.             -- we must check for an environment line 
  4366.             old_env_code := env_code ;
  4367.             if new_string_length > 0 then
  4368.               convert_string_to_header( copy_string(1..new_string_length),
  4369.                                         env_code, copy_header , no_buffer );
  4370.             else
  4371.               env_code := -1 ;
  4372.             end if ;
  4373.             if ( old_env_code = 0 ) and then ( env_code < 0 ) then
  4374.               -- no environment found, look for user's environment
  4375.               users_default_header(copy_header) ;
  4376.             end if ;
  4377.           end if ;
  4378.         exit when env_code < 0 ;
  4379.         end loop ;
  4380.         if env_code >= 0 then
  4381.           -- abnormal exit
  4382.           empty_environment(copy_header);
  4383.           return false ;
  4384.         else
  4385.           -- check markers....
  4386.           if first_marker = blank_marker then
  4387.             ok := true ;
  4388.             first_line_to_move_in := 1 ;
  4389.             first_col_to_move_in  := 1 ;
  4390.           else
  4391.             -- must check a marker...
  4392.             mark_place := find_marker( first_marker ) ;
  4393.             if mark_place > 0 then
  4394.               ok := true ;
  4395.               first_line_to_move_in 
  4396.                       := copy_header.markers(mark_place).location.data.line ;
  4397.               first_col_to_move_in
  4398.                       := copy_header.markers(mark_place).location.data.column ;
  4399.             else
  4400.               ok := false ;
  4401.               error("Marker """ & compress(first_marker) 
  4402.                                 & """ does not exist in file." ,
  4403.                     not_fatal_error , operator_wait , medium_beep ) ;
  4404.             end if ;
  4405.           end if ;
  4406.           if ok then
  4407.             if last_marker = blank_marker then
  4408.               last_line_to_move_in := integer'last ;
  4409.               last_col_to_move_in  := integer'last ;
  4410.             else
  4411.               -- must check a marker...
  4412.               mark_place := find_marker( last_marker ) ;
  4413.               if mark_place > 0 then
  4414.                 ok := true ;
  4415.                 last_line_to_move_in
  4416.                         := copy_header.markers(mark_place).location.data.line ;
  4417.                 last_col_to_move_in
  4418.                         := copy_header.markers(mark_place).location.data.column
  4419.                            - 1 ;
  4420.               else
  4421.                 ok := false ;
  4422.                 error("Marker """ & compress(last_marker)
  4423.                                   & """ does not exist in file." ,
  4424.                       not_fatal_error , operator_wait , medium_beep ) ;
  4425.               end if ;
  4426.             end if ;
  4427.             if ok then
  4428.               -- check for sequencing ..
  4429.               if ( first_line_to_move_in > last_line_to_move_in ) then
  4430.                 ok := false ; -- lines out of order 
  4431.               elsif first_line_to_move_in = last_line_to_move_in then
  4432.                 ok := first_col_to_move_in <= last_col_to_move_in ;
  4433.               end if ;
  4434.               if not ok then
  4435.                 error("Marker """ & compress(first_marker)
  4436.                       & """ must precede """ & compress(last_marker) & """." ,
  4437.                       not_fatal_error , operator_wait , medium_beep ) ;
  4438.               end if ;
  4439.             end if ;
  4440.           end if ;
  4441.           if ok then
  4442.             return true ;
  4443.           else
  4444.             empty_environment(copy_header);
  4445.             return false ;
  4446.           end if ;
  4447.         end if ;
  4448.       end work_environment ;
  4449.        
  4450.       procedure read_text is 
  4451.         -- return true if we successfull moved past environment
  4452.         not_to_do : integer ;
  4453.         text_not_to_do : integer ;
  4454.       begin -- read_text
  4455.         open_buffer(which_buffer,which_buffer.fixed_cursor.line_start,
  4456.                        bytes_needed_for_load );
  4457.           -- Open up a text area here so that we can insert the file
  4458.         current_line_reading := 1 ;
  4459.         loop
  4460.           ln_start := which_buffer.first_open_position ;
  4461.           if current_line_reading >= first_line_to_move_in then
  4462.             if new_string_length > 0 then
  4463.               interpret_string(copy_string(1..new_string_length),
  4464.                                leading_blanks,first_char,
  4465.                                last_char , length ) ;
  4466.             else
  4467.               leading_blanks := 0 ;
  4468.               length         := 0 ;
  4469.             end if ;
  4470.             --
  4471.             -- Note: No matter what, we start this on a line start and end
  4472.             -- at the end of a line....
  4473.             --
  4474.             if current_line_reading = first_line_to_move_in then
  4475.               -- must adjust settings ...
  4476.               if first_col_to_move_in > leading_blanks + 1 then
  4477.                 -- we don't want the leading blanks......
  4478.                 not_to_do := first_col_to_move_in - leading_blanks - 1 ;
  4479.                 text_not_to_do := not_to_do + leading_blanks ;
  4480.                 leading_blanks := 0 ;
  4481.                 if not_to_do >= length then
  4482.                   first_char := 0 ;
  4483.                   last_char  := 0 ;
  4484.                   length     := 0 ;
  4485.                 else
  4486.                   first_char := first_char + not_to_do ;
  4487.                   length     := length     - not_to_do ;
  4488.                   if current_line_reading = last_line_to_move_in then
  4489.                     -- must specially treat first_line = last_line
  4490.                     last_col_to_move_in := last_col_to_move_in - text_not_to_do;
  4491.                   end if ;
  4492.                 end if ;
  4493.               else
  4494.                 null ; -- if they have a marker set at start of line or
  4495.                        -- within leading spaces or at first character,
  4496.                        -- we move over all leading spaces...
  4497.               end if ;
  4498.             -- else do nothing...
  4499.             end if ;
  4500.             -- we stop here and check last line because it could both start
  4501.             -- and stop on the same line 
  4502.             if current_line_reading = last_line_to_move_in then
  4503.               -- again, must adjust settings ...
  4504.               -- first, adjust last_col_to_move_in by the number of 
  4505.               -- characters already deleted on this line
  4506.         exit when last_col_to_move_in <= leading_blanks ;
  4507.               -- exit if we don't want any part of this line.....
  4508.               -- we get here if we want part of this line....
  4509.               if last_col_to_move_in < leading_blanks + length then
  4510.                 -- must get rid of a few characters 
  4511.                 not_to_do := leading_blanks + length 
  4512.                              - last_col_to_move_in ;
  4513.                 length := length - not_to_do ;
  4514.                 last_char := last_char - not_to_do ;
  4515.               end if ;
  4516.             end if ;
  4517.             which_buffer.e_buf(ln_start).data := extended_character(length) ;
  4518.             which_buffer.e_buf(ln_start+1 ).data := 
  4519.                                             extended_character(leading_blanks) ;
  4520.             if length > 0 then
  4521.               for place in 1 .. length loop
  4522.                 which_buffer.e_buf(ln_start + 1 + place ).data :=
  4523.                     extended_character( 
  4524.                          character'pos(copy_string( first_char + place - 1 ) ));
  4525.               end loop ;
  4526.             end if ;
  4527.             which_buffer.e_buf(ln_start + length + 2 ).data := 
  4528.                                                     extended_character(length) ;
  4529.             which_buffer.first_open_position := ln_start + length + 3  ;
  4530.             lines_added := lines_added + 1 ;
  4531.             for place in ln_start .. ln_start + length + 2 loop
  4532.               which_buffer.e_buf(place).attr := no_screen_attribute ;
  4533.             end loop ;
  4534.             if which_buffer.first_open_position + minimum_open_area 
  4535.                        > which_buffer.last_open_position then
  4536.               -- need to bump 
  4537.               push_data(which_buffer,thetop,successfull);
  4538.               if not successfull then
  4539.                 error("Unable To Read/Write Temporary Files.",
  4540.                        not_fatal_error , operator_wait , medium_beep ) ;
  4541.               end if ;
  4542.         exit when not successfull ;
  4543.             end if;
  4544.           end if ;
  4545.           ln_start := which_buffer.first_open_position ;
  4546.         exit when text_io.end_of_file(copyfile);
  4547.           text_io.get_line(copyfile,copy_string,new_string_length);
  4548.         exit when text_io.end_of_file(copyfile) and new_string_length = 0 ;
  4549.           current_line_reading := current_line_reading + 1 ;
  4550.         exit when current_line_reading > last_line_to_move_in ;
  4551.         end loop ;
  4552.           -- Data loaded
  4553.         which_buffer.fixed_cursor := ( 0 , original_line_number + lines_added ,
  4554.                                        ln_start , 1 ) ;
  4555.         which_buffer.first_open_position := ln_start ;
  4556.         close_buffer(which_buffer);
  4557.       end read_text ;
  4558.        
  4559.     begin -- copy_file
  4560.       -- Later we might want to completely work with copy buffer
  4561.       file_copied := file_to_copy ;
  4562.       open_for_read(copyfile,file_copied ,ok);
  4563.       if not ok then
  4564.         error("Bad Copy File Name.",
  4565.                not_fatal_error , operator_wait , medium_beep ) ;
  4566.         return ;
  4567.         -- error.  should not be able to get here
  4568.       end if ;
  4569.       if text_io.end_of_file(copyfile) then
  4570.         -- File not found, even though the caller assured us that it would
  4571.         -- really exist.
  4572.         text_io.close(copyfile);
  4573.       else
  4574.         -- OK!
  4575.         if work_environment then 
  4576.           which_buffer.copy_file_name := file_copied ;
  4577.           original_line_number:= which_buffer.fixed_cursor.file_line_number ;
  4578.           lines_added         := 0 ;
  4579.           read_text ;
  4580.           -- Now, adjust markers for lines_added from original_line_number 
  4581.           adjust_markers(original_line_number,0,
  4582.                          original_line_number + lines_added,0);
  4583.           merge_environment(which_buffer.pagezero,copy_header ) ;
  4584.           empty_environment(copy_header);
  4585.         end if ;
  4586.         text_io.close(copyfile);
  4587.         -- merge the new environment w/marker line offset 
  4588.         -- specified 
  4589.         -- Finally, fix the cursor position 
  4590.         -- jump_to_position (which_buffer,original_line_number, 0);
  4591.         -- which_buffer.cursor.column_offset :=
  4592.                  -- num_leading_spaces(which_buffer,which_buffer.cursor) + 1 ;
  4593.       end if ; -- we actually had a file out there 
  4594.     end copy_file ;
  4595.       
  4596.     procedure dispose_buffer( which_buffer : in out an_editor_buffer ) is
  4597.       -- close a buffer because we are done with it
  4598.       successfull : boolean ;
  4599.     begin -- dispose_buffer
  4600.       for psh in topush'first .. topush'last loop
  4601.         close   ( which_buffer , psh , successfull ) ;
  4602.            -- close the block file 
  4603.       end loop ;
  4604.      
  4605.       -- and then get rid of its memory requirements....
  4606.        
  4607.     end dispose_buffer ;
  4608.          
  4609.   begin -- buffer_package
  4610.     -- BUFFERS  by SAIC/Clearwater Buffer Package              17 Jan 85
  4611.     null ;
  4612.   end buffer_package ;
  4613.        
  4614.   --$$$- BUFFERS
  4615.  
  4616. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4617. --editmisc
  4618. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4619.  
  4620.   --$$$+ EDITMISC
  4621.     
  4622.   --
  4623.   -- File 016
  4624.   --
  4625.   -- Editor Written By Robert S. Cymbalski
  4626.   --                   Science Applications International Corporation
  4627.   --                   Ada Software Development Project Team
  4628.   --
  4629.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  4630.   -- 
  4631.  
  4632.   with basic_io_system ;
  4633.    
  4634.   with text_io ;
  4635.    
  4636.   with direct_io ;
  4637.    
  4638.   with string_library  ;
  4639.   use  string_library  ;
  4640.    
  4641.   with crt_customization ;
  4642.   use  crt_customization ;
  4643.   use  crt               ;
  4644.   use  editor_customization ;
  4645.     
  4646.   with crt_windows    ;
  4647.    
  4648.   with Wordp_Globals   ;
  4649.   use  Wordp_Globals   ;
  4650.  
  4651.   with editor_globals ;
  4652.   use  editor_globals ;
  4653.               
  4654.   with edit_windows   ;
  4655.   use  edit_windows   ;
  4656.       
  4657.   with buffer_package  ;
  4658.   use  buffer_package  ;
  4659.   use  buffer_general  ;
  4660.   use  buffer_lines    ;
  4661.    
  4662.   with markers         ;
  4663.   use  markers         ;
  4664.   use  text_position_handler    ;
  4665.  
  4666.   package editor_misc is
  4667.             
  4668.     package copy_package is
  4669.      
  4670.       Procedure Copy_Text_To_Copy_Buffer(which_buffer: in out an_editor_buffer ;
  4671.                                          copy_range  : text_range       ;
  4672.                                          add_to_previous_copy : boolean :=false;
  4673.                                          delete_after_copy : boolean:=false ;
  4674.                                          adjust_markers : boolean := true ) ;
  4675.         -- copy the text within the range to the copy buffer
  4676.         -- then, optionally, delete the text......
  4677.      
  4678.       procedure Copy_Text_Back_From_Copy_Buffer ( which_buffer :
  4679.                                                   in out an_editor_buffer ) ;
  4680.       
  4681.       procedure copy_debug ( c : character ) ;
  4682.        
  4683.       procedure terminate_copy_package ;
  4684.        
  4685.     end copy_package ;
  4686.      
  4687.     master_buffer      : editor_globals.an_editor_buffer ;
  4688.     master_window      : crt_windows.window_pointer          ;
  4689.        
  4690.     procedure set_direction ( go_forward : boolean ) ;
  4691.       -- Set the direction arrow at the top left corner
  4692.       
  4693.     procedure set_repeat_prompt( is_show_repeat_on : boolean ;
  4694.                                  repeat_factor     : a_repeat_factor ) ;
  4695.       -- If is_show_repeat_on, the set the repeat factor string
  4696.       -- as stated in repeat_factor.  If it is -1, then set it
  4697.       -- as [Once].  
  4698.         
  4699.     procedure prompt ( prompt_string : in string ) ;
  4700.       -- show the prompt string in the master buffer
  4701.         
  4702.     procedure show_screen( which_buffer : in out an_editor_buffer ) ;
  4703.                -- Given the current screen definition, show the entire 
  4704.                -- screen within the current window.
  4705.                    
  4706.     procedure show_screen( which_buffer : in out an_editor_buffer ;
  4707.                            cursor       : in out cursor_position  ;
  4708.                            Cursor_Line  : in window_line_number   ) ;
  4709.                -- Given the current screen definition, show the entire 
  4710.                -- screen within the current window.
  4711.                -- The cursor is to be put on cursor_line if possible.
  4712.                -- Note: cursor might be found as both CURSOR and
  4713.                -- WHICH_BUFFER.fixed_CURSOR
  4714.                  
  4715.     procedure show_cursor ;
  4716.       -- move the actual cursor to the position on the screen where the
  4717.       -- master buffer's logical cursor is
  4718.       
  4719.     procedure show_cursor ( which_buffer : in out an_editor_buffer ) ;
  4720.                -- Show the cursor on the screen.  If necessary, push/pop
  4721.                -- data to make sure you have enough for the entire screen
  4722.                  
  4723.     procedure jump_to_position ( which_buffer     : in out an_editor_buffer ;
  4724.                                  to_line_number   : in line_number          ;
  4725.                                  to_column_number : in column_position      ;
  4726.                                  show_new_position: in boolean := true    ) ;
  4727.                -- Move the cursor and screen display to the specified
  4728.                -- position.  
  4729.                    
  4730.     function current_position return text_position ;
  4731.          -- return the line/column/and buffer for the current position
  4732.   
  4733.     function cursor_forward_line return boolean ;
  4734.       -- return true if we moved forward a line like we were asked
  4735.   
  4736.     function cursor_backward_line return boolean ;
  4737.       -- return true if we moved backward a line like we were asked
  4738.     
  4739.     procedure get_leading ( txt : in out type_text_line ;
  4740.                             leading_spaces : out type_leading_spaces  ;
  4741.                             first_text_position,
  4742.                             last_text_position:out type_text_length ;
  4743.                             length : out type_line_length  ) ; 
  4744.       -- take a txt line and get facts necessary for insertion into
  4745.       -- the buffer.  truncate any values necessary to force it to
  4746.       -- be a valid line...
  4747.    
  4748.     procedure get_next_command( Old_Repeat : in  a_repeat_factor ;
  4749.                                 New_Repeat : out a_repeat_factor ;
  4750.                                 new_command : out an_editor_command ) ;
  4751.    
  4752.     allow_alternate_prompt_command : boolean := true ;
  4753.       
  4754.   private
  4755.    
  4756.     is_go_forward : boolean        ;
  4757.     repeat_prompt : string_library.pstring ;
  4758.     last_repeat   : integer        ;
  4759.     prompt_line   : string_library.pstring ;
  4760.       
  4761.     reverse_storage : boolean := false ;
  4762.       
  4763.   end editor_misc ;
  4764.       
  4765.   package body editor_misc is 
  4766.    
  4767.   package body copy_package is
  4768.        
  4769.     package copy_block_io is new direct_io(block);
  4770.      
  4771.     type Type_Copy_Data is 
  4772.            record
  4773.              Present_Copy_Block   : Integer      := 0       ;
  4774.              Present_Copy_Length  : block_offset := 0       ;
  4775.              We_Have_Copy_Data    : boolean      := false   ;
  4776.              The_Copy_Buffer      : block;
  4777.              Copy_Started_At_Stuff_Start : boolean := false ;
  4778.              Copy_Ended_At_Line_End      : boolean := false ;
  4779.              Copy_Ended_At_Stuff_Start   : boolean := false ;
  4780.              Copy_File            : copy_block_io.file_type ;
  4781.            end record ;
  4782.        
  4783.     Type Copy_Data_Pointer is access Type_Copy_Data ;
  4784.      
  4785.     The_Copy_Data     : Copy_Data_Pointer ;
  4786.      
  4787.     Current_Copy_Data : Copy_Data_Pointer ;
  4788.      
  4789.     procedure copy_debug ( c  : character ) is
  4790.      
  4791.       procedure show ( s : string ; b : boolean ) is
  4792.       begin 
  4793.         put(s);
  4794.         if b then put_line("True"); else put_line("False"); end if ;
  4795.       end ;
  4796.        
  4797.       procedure show_insides( b : block ) is
  4798.         p1 : block_offset := 0 ;
  4799.         p2 : integer := current_copy_data.present_copy_length - 1 ;
  4800.         ln_start : integer ;
  4801.         ln_posn : block_offset ;
  4802.        
  4803.         procedure show_c ( val , len : integer ) is
  4804.         begin
  4805.           if val < 0 then
  4806.             basic_io_system.put(" XXX");
  4807.           elsif val < 32 then
  4808.             basic_io_system.put(val,len);
  4809.           elsif val < 127 then
  4810.             basic_io_system.put("  """);
  4811.             basic_io_system.put( character'val(val));
  4812.           elsif val <= 999 then
  4813.             basic_io_system.put(val,len);
  4814.           else
  4815.             basic_io_system.put(" XXX");
  4816.           end if ;
  4817.         end ;
  4818.          
  4819.       begin
  4820.         basic_io_system.put_line ;
  4821.         ln_start := p1 ;
  4822.         loop
  4823.           basic_io_system.put(ln_start,5);
  4824.           basic_io_system.put("  ");
  4825.           ln_posn := ln_start ;
  4826.           loop
  4827.             show_c( b(ln_posn).data , 4 ) ;
  4828.             ln_posn := ln_posn + 1 ;
  4829.           exit when ( ln_posn = ln_start + 16 ) or ( ln_posn > p2 ) ;
  4830.           end loop ;
  4831.           basic_io_system.put_line;
  4832.           ln_start := ln_start + 16 ;
  4833.         exit when ln_start > p2 ;
  4834.         end loop ;
  4835.       end;
  4836.        
  4837.     begin -- copy_debug
  4838.       case c is
  4839.         when 'X' => put_line(" ");
  4840.                     put("  Present Copy Block => ");
  4841.                     put( current_copy_data.present_copy_block , 3 ) ;
  4842.                     put_line("  ");
  4843.                     put("  Present Copy Leng  => ");
  4844.                     put( current_copy_data.Present_Copy_Length , 4 ) ;
  4845.                     put_line("  ");
  4846.       show("Copy Available   " , current_copy_data.We_Have_Copy_Data);
  4847.       show("Start StuffStart " , current_copy_data.Copy_Started_At_Stuff_Start);
  4848.       show("End Line End     " , current_copy_data.Copy_Ended_At_Line_End     );
  4849.       show("End StuffStart   " , current_copy_data.Copy_Ended_At_Stuff_Start  );
  4850.         when 'B' => show_insides( current_copy_data.The_Copy_Buffer ) ;
  4851.         when others => null ;
  4852.       end case ;
  4853.     end copy_debug ;
  4854.      
  4855.     procedure initialize_copy_package is
  4856.     begin -- initialize_copy_package
  4857.      copy_block_io.create(Current_Copy_Data.Copy_File,copy_block_io.inout_file);
  4858.     exception 
  4859.       when others => error( "Unable To Open Temporary Copy File.",
  4860.                             fatal_error,operator_wait , long_beep ) ;
  4861.     end initialize_copy_package ;
  4862.    
  4863.     procedure terminate_copy_package is
  4864.     begin -- terminate_copy_package
  4865.       copy_block_io.close ( Current_Copy_Data.Copy_File ) ;
  4866.     exception 
  4867.       when others => null ;
  4868.     end terminate_copy_package ;
  4869.    
  4870.     procedure getblock( block_of_data: out    block   ;
  4871.                         block_number : in     integer ;
  4872.                         successfull  : out    boolean ) is  
  4873.                -- read in a block of data from that file
  4874.     begin -- getblock
  4875.       copy_block_io.read( Current_Copy_Data.Copy_File , block_of_data ,
  4876.                           copy_block_io.positive_count(block_number)) ;
  4877.       successfull := true ; 
  4878.     exception 
  4879.       when others => successfull := false ;
  4880.     end getblock ;
  4881.      
  4882.     procedure putblock( block_of_data: in     block   ;
  4883.                         block_number : in     integer ;
  4884.                         successfull  : out    boolean ) is  
  4885.                -- write a block of data from that file
  4886.       wicat_block : block := block_of_data ;
  4887.     begin -- putblock
  4888.       copy_block_io.write(Current_Copy_Data.Copy_File , wicat_block   ,
  4889.                           copy_block_io.positive_count(block_number)) ;
  4890.       successfull := true ; 
  4891.     exception 
  4892.       when others => successfull := false ;
  4893.     end putblock ;
  4894.  
  4895.     Procedure Copy_Text_To_Copy_Buffer( which_buffer: in out an_editor_buffer ;
  4896.                                         copy_range  : text_range       ;
  4897.                                         add_to_previous_copy : boolean := false;
  4898.                                         delete_after_copy : boolean:=false ;
  4899.                                         adjust_markers : boolean := true ) is
  4900.       First_Pos , 
  4901.       Second_Pos : Text_Position ;
  4902.       Actual_Copy_Range : Text_Range ;
  4903.       Original_Location : Text_Position ;
  4904.       should_delete_extra_leading   : boolean              ;
  4905.       Original_Leading_Spaces       : type_leading_spaces  ;
  4906.       Fixed_Cursor_Line_Start       : type_buffer_position ;
  4907.       Fixed_Cursor_Buffer_Position  : type_buffer_position ;
  4908.       First_Line_Character_Position : type_buffer_position ;
  4909.       Last_Line_Character_Position  : type_buffer_position ;
  4910.       Lines_Leading_Spaces          : type_leading_spaces  ;
  4911.       Lines_Last_Column             : column_position      ;
  4912.       Lines_Text_Length             : type_line_length     ;
  4913.       next_copy_position            : block_offset := 
  4914.                                          Current_Copy_Data.Present_Copy_Length ;
  4915.       no_room_to_copy_text          : exception            ;
  4916.       -- now items for the deletion
  4917.       First_Deleted_Position        : type_buffer_position := 1 ;
  4918.       Last_Deleted_Position         : type_buffer_position := 0 ;
  4919.       -- the above two settings make it so that we know nothing is deleted
  4920.       orig_text : type_text_line ;
  4921.       orig_col  : column_position ;
  4922.       orig_line_number : line_number ;
  4923.       type a_place is ( in_leading , at_stuff_start , 
  4924.                         in_text , at_text_end , past_end_of_line ) ;
  4925.       left_place , right_place : a_place ;
  4926.        
  4927.       procedure new_block is
  4928.         successfull : boolean ;
  4929.       begin -- new_block
  4930.         Current_Copy_Data.Present_Copy_Block 
  4931.                                  := Current_Copy_Data.Present_Copy_Block + 1 ;
  4932.         putblock( Current_Copy_Data.The_Copy_Buffer ,
  4933.                   Current_Copy_Data.Present_Copy_Block , successfull ) ;
  4934.         if successfull then
  4935.           next_copy_position := 0 ;
  4936.         else
  4937.           -- error....
  4938.           error(" Unable To Copy Text To Disk..." ,
  4939.                 not_fatal_error ,operator_wait ,short_beep ) ;
  4940.           raise no_room_to_copy_text ;
  4941.         end if ;
  4942.       end new_block ;
  4943.          
  4944.       Procedure Add_Ch_To_Buffer 
  4945.                                                 ( C : in extended_character ) is
  4946.         -- add one extended character to buffer
  4947.       begin -- Add_Ch_To_Buffer 
  4948.         Current_Copy_Data.The_Copy_Buffer( next_copy_position ).data := c ;
  4949.         if next_copy_position = block_minus then
  4950.           new_block ;
  4951.         else
  4952.           next_copy_position := next_copy_position + 1 ;
  4953.         end if ;
  4954.       end Add_Ch_To_Buffer ;
  4955.        
  4956.       Procedure Add_One_Character_To_Buffer ( C : in character ) is
  4957.       begin -- add_one_character_to_buffer 
  4958.         Current_Copy_Data.The_Copy_Buffer( next_copy_position ).data := 
  4959.                       extended_character( character'pos( c ) ) ;
  4960.         if next_copy_position = block_minus then
  4961.           new_block ;
  4962.         else
  4963.           next_copy_position := next_copy_position + 1 ;
  4964.         end if ;
  4965.       end add_one_character_to_buffer ;
  4966.        
  4967.       Function Backup_One_Character_From_Buffer return character is
  4968.         successfull : boolean ;
  4969.         next_extended : extended_character ;
  4970.       begin -- backup_one_character_from_buffer
  4971.         if next_copy_position = 0 then
  4972.           -- we need to be carefull.....
  4973.           if current_copy_data.present_copy_block = 0 then
  4974.             return ascii.nul ; -- can't back up any more 
  4975.           else
  4976.             Current_Copy_Data.Present_Copy_Block 
  4977.                                    := Current_Copy_Data.Present_Copy_Block - 1 ;
  4978.             getblock( Current_Copy_Data.The_Copy_Buffer ,
  4979.                       Current_Copy_Data.Present_Copy_Block , successfull ) ;
  4980.             if successfull then
  4981.               next_copy_position := block_minus ;
  4982.             else
  4983.               -- error....
  4984.               error(" Unable To Add Copy Text To Disk..." ,
  4985.                     not_fatal_error ,operator_wait ,short_beep ) ;
  4986.               raise no_room_to_copy_text ;
  4987.             end if ;
  4988.           end if ;
  4989.         end if ;
  4990.         -- if we get this far... then we can read the next character ...
  4991.         next_copy_position := next_copy_position - 1 ;
  4992.         next_extended := Current_Copy_Data.The_Copy_Buffer(
  4993.                                                      next_copy_position ).data ;
  4994.         if next_extended <= extended_character(character'pos(character'last))
  4995.         then
  4996.           return character'val( next_extended ) ;
  4997.         else
  4998.           return ascii.del ;
  4999.         end if ;
  5000.       end backup_one_character_from_buffer ;
  5001.        
  5002.       Procedure Fix_Fixed_Cursor is
  5003.         -- note the boundries of the current line for searching
  5004.       begin -- fix_fixed_cursor
  5005.         Fixed_Cursor_Line_Start       := which_buffer.fixed_cursor.line_start ;
  5006.         Lines_Leading_Spaces          := num_leading_spaces ( which_buffer ,
  5007.                                            fixed_cursor_line_start ) ;
  5008.         Lines_Text_Length             := line_length( which_buffer , 
  5009.                                            fixed_cursor_line_start ) ;
  5010.         First_Line_Character_Position := Fixed_Cursor_Line_Start + 2 ;
  5011.         Last_Line_Character_Position  := First_Line_Character_Position
  5012.                                            + Lines_Text_Length - 1 ;
  5013.         Lines_Last_Column             := Lines_Leading_Spaces 
  5014.                                            + Lines_Text_Length ;
  5015.       end fix_fixed_Cursor ;
  5016.        
  5017.       function is_at_stuff_start ( cursor : cursor_position ) return boolean is
  5018.         save_cursor : cursor_position := which_buffer.fixed_cursor ;
  5019.         return_value : boolean ;
  5020.       begin -- is_at_stuff_start
  5021.         which_buffer.fixed_cursor := cursor ;
  5022.         fix_fixed_cursor ;
  5023.         return_value := ( lines_text_length < 1 ) 
  5024.                   or else ( cursor.column_offset <= lines_leading_spaces + 1 ) ;
  5025.         which_buffer.fixed_cursor := save_cursor ;
  5026.         fix_fixed_cursor ;
  5027.         return return_value ;
  5028.       end is_at_stuff_start ;
  5029.        
  5030.       function is_at_line_end ( cursor : cursor_position ) return boolean is
  5031.         save_cursor : cursor_position := which_buffer.fixed_cursor ;
  5032.         return_value : boolean ;
  5033.       begin -- is_at_line_end
  5034.         which_buffer.fixed_cursor := cursor ;
  5035.         fix_fixed_cursor ;
  5036.         return_value := ( lines_text_length < 1 ) 
  5037.                         or else ( cursor.column_offset > lines_last_column ) ;
  5038.         which_buffer.fixed_cursor := save_cursor ;
  5039.         fix_fixed_cursor ;
  5040.         return return_value ;
  5041.       end is_at_line_end ;
  5042.        
  5043.       procedure copy_out_initialize is
  5044.         old_c : character ;
  5045.       begin -- copy_out_initialize
  5046.         -- first, make sure lo < hi
  5047.         Actual_Copy_Range := Copy_Range ;
  5048.         Normalize_Range( Actual_Copy_Range ) ;
  5049.         first_pos  := actual_copy_range.lo_position ;
  5050.         second_pos := actual_copy_range.hi_position ;
  5051.         -- now, ready to work...
  5052.         need_prompt := true ;
  5053.         clear_prompt( which_buffer ) ;
  5054.         goto_prompt_line_column( which_buffer , 1 , 1 ) ;
  5055.         if add_to_previous_copy then
  5056.           put(" Adding text to list");
  5057.         else
  5058.           put(" Copying data");
  5059.           Current_Copy_Data.Present_Copy_Block := 0 ;
  5060.           Current_Copy_Data.Present_Copy_Length   := 0 ;
  5061.         end if ;
  5062.         put(" for later C(opy from B(uffer ...");
  5063.         which_buffer.last_marked_position.data := first_pos ;
  5064.         -- the last was for the '=' command
  5065.         if delete_after_copy then
  5066.           -- when done, we must move to the first location remaining after
  5067.           -- we delete the range....which is the starting location
  5068.           Original_Location := First_Pos ;
  5069.           -- and, while we are here, we might as well take care of the
  5070.           -- markers..... because we are deleting text....
  5071.           if adjust_markers then
  5072.             markers.marker_manager.update_markers_for_deleted_text( 
  5073.                                     which_buffer , actual_copy_range ) ;
  5074.           end if ;
  5075.         else
  5076.           -- remember where we have to move to...
  5077.           Original_Location := ( which_buffer.fixed_cursor.file_line_number ,
  5078.                                  which_buffer.fixed_cursor.column_offset    ,
  5079.                                  no_screen_attribute ,
  5080.                                  which_buffer ) ;
  5081.           -- and, while we are here, we might as well take care of the
  5082.           -- markers..... because we added text.....
  5083.           if adjust_markers then
  5084.             markers.marker_manager.update_markers_for_added_text(
  5085.                                     which_buffer , actual_copy_range ) ;
  5086.           end if ;
  5087.         end if ;
  5088.         jump_to_position ( which_buffer , first_pos.line , first_pos.column ,
  5089.                            false ) ;
  5090.         fix_fixed_cursor ;
  5091.         Original_Leading_Spaces := Lines_Leading_Spaces ;
  5092.         if first_pos.column = original_leading_spaces + 1 then
  5093.           -- they are at the first character of the line
  5094.           -- must back up first position .....
  5095.           should_delete_extra_leading := true ;
  5096.         else
  5097.           should_delete_extra_leading := false ;
  5098.         end if ;
  5099.         If add_to_previous_copy 
  5100.         and then current_copy_data.we_have_copy_data then
  5101.           -- ok, we need to adjust any ending positions.....
  5102.           If is_at_stuff_start ( which_buffer.fixed_cursor ) then
  5103.             -- in this case, we might adjust some old information...
  5104.             if current_copy_data.copy_ended_at_stuff_start then
  5105.               -- back up to the <cr>.......
  5106.               loop
  5107.                 old_c := backup_one_character_from_buffer ;
  5108.               exit when old_c = ascii.nul or old_c = ascii.cr ;
  5109.               end loop ;
  5110.               if old_c = ascii.cr then
  5111.                 add_one_character_to_buffer ( ascii.cr ) ;
  5112.               end if ;
  5113.             else
  5114.               -- ended either at line end or in the middle...
  5115.               -- simply add a <cr> to the old buffer to nicely add on this
  5116.               -- new info..
  5117.               add_one_character_to_buffer( ascii.cr ) ;
  5118.             end if ;
  5119.           -- else, do nothing to the old area.....
  5120.           end if ;
  5121.           next_copy_position := Current_Copy_Data.Present_Copy_Length ;
  5122.         else
  5123.           -- set the copy start information
  5124.           Current_Copy_Data.Copy_Started_At_Stuff_Start 
  5125.                     := is_at_stuff_start ( which_buffer.fixed_cursor ) ;
  5126.           Current_Copy_Data.Present_Copy_Block  := 0 ;
  5127.           Current_Copy_Data.Present_Copy_Length := 0 ;
  5128.           next_copy_position := 0 ;
  5129.         end if ;
  5130.       end copy_out_initialize ;
  5131.      
  5132.       Procedure Copy_Out_Finish is
  5133.       begin -- copy_out_finish 
  5134.         Current_Copy_Data.We_Have_Copy_Data := 
  5135.                      Current_Copy_Data.Present_Copy_Length > 0 
  5136.              or else Current_Copy_Data.Present_Copy_Block  > 0 ;
  5137.         Current_Copy_Data.Copy_Ended_At_Stuff_Start
  5138.                   := is_at_stuff_start ( which_buffer.fixed_cursor ) ;
  5139.         Current_Copy_Data.Copy_Ended_At_Line_End
  5140.                   := is_at_line_end    ( which_buffer.fixed_cursor ) ;
  5141.       end copy_out_finish ;
  5142.        
  5143.       procedure add_this_line ( leading_spaces : type_leading_spaces ;
  5144.                                 first_pos      : type_buffer_position;
  5145.                                 last_pos       : type_buffer_position;
  5146.                                 ln_length      : type_line_length    ;
  5147.                                 add_return     : boolean := true     ) is
  5148.         remaining_length : integer := ln_length ;
  5149.         next_char        : type_buffer_position := first_pos ;
  5150.         amount_moved     : integer ;
  5151.       begin -- add_this_line 
  5152.         if leading_spaces > 0 then
  5153.           add_one_character_to_buffer( ascii.dle ) ;
  5154.           Add_Ch_To_Buffer( extended_character ( leading_spaces ) ) ;
  5155.         end if ; -- end of leading spaces 
  5156.         while remaining_length > 0 loop
  5157.           -- in case all does not fit in copy buffer....
  5158.           if next_copy_position + remaining_length <= block_minus then
  5159.             -- can move over in a block...
  5160.             for looper in 0 .. remaining_length - 1 loop
  5161.               Current_Copy_Data.The_Copy_Buffer( next_copy_position + looper )
  5162.                           := which_buffer.e_buf( next_char + looper ) ;
  5163.             end loop ;
  5164.             if next_copy_position + remaining_length = block_minus then
  5165.               new_block ;
  5166.             else
  5167.               next_copy_position := next_copy_position + remaining_length ;
  5168.             end if ;
  5169.             remaining_length := 0 ;
  5170.           else
  5171.             -- must move some and then return...
  5172.             amount_moved := block_minus - next_copy_position ;
  5173.               -- actually, amount moved is one LESS than amount moved...
  5174.             for looper in 0 .. amount_moved loop
  5175.               Current_Copy_Data.The_Copy_Buffer( next_copy_position + looper )
  5176.                           := which_buffer.e_buf( next_char + looper ) ;
  5177.             end loop ;
  5178.             new_block ;
  5179.             remaining_length := remaining_length - amount_moved - 1 ;
  5180.             next_char := next_char + amount_moved + 1 ;
  5181.           end if ;
  5182.         end loop ;
  5183.         if add_return then
  5184.           add_one_character_to_buffer( ascii.cr ) ;
  5185.         end if ; -- end of adding carriage return....
  5186.       end add_this_line ;
  5187.        
  5188.       procedure replace_current_text ( txt : in out type_text_line ) is
  5189.         lspaces : type_leading_spaces;
  5190.         tfirst  , tlast  : type_text_length;
  5191.         tlength : type_line_length;
  5192.         olength : type_line_length;
  5193.         lstart  : type_buffer_position;
  5194.         old_nxtln ,
  5195.         new_nxtln : type_buffer_position;
  5196.       begin -- replace_current_text 
  5197.         get_leading ( txt , lspaces , tfirst , tlast , tlength );
  5198.         lstart := which_buffer.fixed_cursor.line_start;
  5199.         olength   := line_length( which_buffer , lstart );
  5200.         old_nxtln := lstart + olength + 3;
  5201.         new_nxtln := lstart + tlength + 3;
  5202.         shift_buffer_area ( which_buffer , old_nxtln , new_nxtln , 
  5203.                             which_buffer.bufcount - old_nxtln + 1 );
  5204.         which_buffer.bufcount:=which_buffer.bufcount -olength +tlength;
  5205.         which_buffer.e_buf(lstart).data    
  5206.                                 := extended_character(tlength);
  5207.         which_buffer.e_buf(lstart+1 ).data 
  5208.                                 := extended_character(lspaces);
  5209.         for place in 1 .. tlength loop
  5210.           which_buffer.e_buf(lstart + 1 + place ).data :=
  5211.                         txt.data(tfirst+place-1);
  5212.         end loop;
  5213.         which_buffer.e_buf(lstart + tlength + 2 ).data 
  5214.                                 := extended_character(tlength);
  5215.         for place in lstart .. lstart + tlength + 2 loop
  5216.           which_buffer.e_buf(place).attr := no_screen_attribute;
  5217.         end loop;
  5218.       end replace_current_text;
  5219.  
  5220.       procedure determine_left_and_right ( l_col , r_col : column_position ) is
  5221.       -- type a_place is ( in_leading , at_stuff_start , 
  5222.                         -- in_text , at_text_end , past_end_of_line ) ;
  5223.       -- left_place , right_place : a_place ;
  5224.       begin -- determine_left_and_right
  5225.         fix_fixed_cursor ;
  5226.         if l_col > lines_last_column then
  5227.           left_place    := past_end_of_line ;
  5228.           right_place   := past_end_of_line ;
  5229.         else
  5230.           if    l_col < lines_leading_spaces + 1 then
  5231.             if lines_leading_spaces = 0 then
  5232.               left_place  := past_end_of_line ;
  5233.             else
  5234.               left_place  := in_leading       ;
  5235.             end if ;
  5236.           elsif l_col = lines_leading_spaces + 1 then
  5237.             left_place  := at_stuff_start   ;
  5238.           elsif l_col < lines_last_column        then
  5239.             left_place  := in_text          ;
  5240.           else
  5241.             left_place  := at_text_end      ;
  5242.             -- because the past_end_of_line is taken care of above...
  5243.           end if ;
  5244.           if r_col < lines_leading_spaces + 1 then
  5245.             if lines_leading_spaces = 0 then
  5246.               right_place := past_end_of_line ;
  5247.             else
  5248.               right_place := in_leading       ;
  5249.             end if ;
  5250.           elsif r_col = lines_leading_spaces + 1 then
  5251.             right_place := at_stuff_start   ;
  5252.           elsif r_col < lines_last_column        then
  5253.             right_place := in_text          ;
  5254.           elsif r_col = lines_last_column        then
  5255.             right_place := at_text_end      ;
  5256.           else
  5257.             right_place := past_end_of_line ;
  5258.           end if ;
  5259.         end if ;
  5260.       end determine_left_and_right ;
  5261.        
  5262.       procedure add_partial_line_to_copy_buffer( in_first_col , in_last_col 
  5263.                                                  : column_position )  is
  5264.         first_pos : type_buffer_position ;
  5265.         last_pos  : type_buffer_position ;
  5266.         ln_length : type_line_length ;
  5267.         first_col : column_position := in_first_col ;
  5268.         last_col  : column_position := in_last_col  ;
  5269.         real_leading_spaces : type_leading_spaces ;
  5270.         txt_to_move : integer ;
  5271.       begin -- add_partial_line_to_copy_buffer 
  5272.         determine_left_and_right ( in_first_col , in_last_col ) ;
  5273.         real_leading_spaces := lines_leading_spaces ;
  5274.         case left_place is
  5275.           when in_leading       => first_pos := first_line_character_position ;
  5276.                                    lines_leading_spaces 
  5277.                                             := lines_leading_spaces 
  5278.                                                 - first_col + 1 ;
  5279.           when at_stuff_start   => first_pos := first_line_character_position ;
  5280.                                    -- lines_leading_spaces is already correct
  5281.           when in_text          => first_pos := first_line_character_position 
  5282.                                                 + first_col
  5283.                                                 - real_Leading_Spaces - 1 ;
  5284.                                    lines_leading_spaces := 0 ;
  5285.           when at_text_end      => first_pos := last_line_character_position  ;
  5286.                                    lines_leading_spaces := 0 ;
  5287.           when past_end_of_line => return ; -- nothing to do if past end
  5288.                                             -- on start position 
  5289.         end case ;
  5290.         case right_place is
  5291.           when in_leading       => last_pos := 0 ;
  5292.                                    if last_col - first_col + 1 >= 0 then
  5293.                                      lines_leading_spaces := last_col
  5294.                                                               - first_col + 1 ;
  5295.                                    else
  5296.                                      lines_leading_spaces := 0 ;
  5297.                                    end if ;
  5298.           when at_stuff_start   => last_pos := first_line_character_position ;
  5299.           when in_text          => last_pos := first_line_character_position 
  5300.                                                + last_col 
  5301.                                                - real_Leading_Spaces - 1 ;
  5302.           when at_text_end      
  5303.              | past_end_of_line => last_pos := last_line_character_position  ;
  5304.                                    last_col := lines_last_column ;
  5305.              -- sometime later we might want to include trailing spaces, and
  5306.              -- then in that case we would break these into two cases.....
  5307.         end case ;
  5308.         if last_pos < first_pos then
  5309.           if lines_leading_spaces = 0 then
  5310.             return ;
  5311.           else
  5312.             ln_length := 0 ;
  5313.           end if ;
  5314.         else
  5315.           ln_length := last_pos - first_pos + 1 ;
  5316.         end if ;
  5317.         add_this_line ( lines_leading_spaces ,
  5318.                         first_pos ,
  5319.                         last_pos ,
  5320.                         ln_length , false ) ;
  5321.         -- Now delete after copy
  5322.         If delete_after_copy then
  5323.           -- must get rid of deleted text....
  5324.           -- and only this text is being deleted...
  5325.           -- we have ORIG_TEXT and know to get rid of FIRST_COL .. LAST_COL 
  5326.           -- and ORIG_TEXT.data_length
  5327.           txt_to_move := orig_text.data_length - last_col ;
  5328.           if txt_to_move > 0 then
  5329.             for pn in 1 .. txt_to_move loop
  5330.               orig_text.data( first_col + pn - 1 ) 
  5331.                           := orig_text.data( last_col + pn ) ;
  5332.             end loop ;
  5333.           end if ;
  5334.           orig_text.data_length := orig_text.data_length 
  5335.                                       - last_col + first_col - 1 ;
  5336.           replace_current_text ( orig_text ) ;
  5337.         end if ;
  5338.       end add_partial_line_to_copy_buffer ;
  5339.        
  5340.       procedure add_end_of_line_to_copy_buffer( 
  5341.                                       in_first_col : in out column_position ) is
  5342.         first_col : column_position := in_first_col ;
  5343.         first_pos : type_buffer_position ;
  5344.         last_pos  : type_buffer_position ;
  5345.         ln_length : type_line_length ;
  5346.         real_leading_spaces : type_leading_spaces ;
  5347.       begin -- add_end_of_line_to_copy_buffer
  5348.         determine_left_and_right ( in_first_col , column_position'last ) ;
  5349.         real_leading_spaces := lines_leading_spaces ;
  5350.         case left_place is
  5351.           when in_leading       => first_pos := first_line_character_position ;
  5352.                                    lines_leading_spaces 
  5353.                                             := lines_leading_spaces 
  5354.                                                 - first_col + 1 ;
  5355.           when at_stuff_start   => first_pos := first_line_character_position ;
  5356.                                    -- lines_leading_spaces is already correct
  5357.           when in_text          => first_pos := first_line_character_position 
  5358.                                                 + first_col
  5359.                                                 - real_Leading_Spaces - 1 ;
  5360.                                    lines_leading_spaces := 0 ;
  5361.           when at_text_end      => first_pos := last_line_character_position  ;
  5362.                                    lines_leading_spaces := 0 ;
  5363.           when past_end_of_line => -- because past right end of line ...
  5364.                                    add_this_line ( 0 , 1 , 0 , 0 , true ) ;
  5365.                                    in_first_col := 0 ; -- signal no info
  5366.                                    return ;
  5367.         end case ;
  5368.         last_pos := last_line_character_position ;
  5369.         ln_length := last_pos - first_pos + 1 ;
  5370.         add_this_line ( lines_leading_spaces ,
  5371.                         first_pos ,
  5372.                         last_pos ,
  5373.                         ln_length , true ) ;
  5374.       end add_end_of_line_to_copy_buffer ;
  5375.        
  5376.       procedure add_line_to_copy_buffer is
  5377.         -- add the line described by fixed_cursor to the copy buffer
  5378.       begin -- add_line_to_copy_buffer 
  5379.         fix_fixed_cursor ;
  5380.         add_this_line ( lines_leading_spaces ,
  5381.                         first_line_character_position ,
  5382.                         last_line_character_position ,
  5383.                         lines_text_length , true ) ;
  5384.       end add_line_to_copy_buffer ;
  5385.        
  5386.       procedure delete_chunk is
  5387.         positions_to_move : integer ;
  5388.       begin -- delete_chunk
  5389.         if delete_after_copy then
  5390.           -- delete first_deleted_position .. last_deleted_position ...
  5391.           if last_deleted_position > first_deleted_position then
  5392.             -- stuff has been deleted...
  5393.             positions_to_move := which_buffer.bufcount - last_deleted_position ;
  5394.             shift_buffer_area( which_buffer , last_deleted_position + 1 ,
  5395.                                               first_deleted_position ,
  5396.                                               positions_to_move ) ;
  5397.             which_buffer.bufcount := first_deleted_position - 1
  5398.                                               + positions_to_move ;
  5399.             which_buffer.fixed_cursor.line_start := first_deleted_position ;
  5400.             last_deleted_position := first_deleted_position - 1 ;
  5401.           end if ;
  5402.         end if ;
  5403.       end delete_chunk ;
  5404.        
  5405.       procedure add_start_of_line_to_copy_buffer( last_col: 
  5406.                                                      in out column_position ) is
  5407.         in_first_col : column_position := 1        ;
  5408.         in_last_col  : column_position := last_col ;
  5409.         last_pos     : type_buffer_position ;
  5410.         ln_length    : type_line_length ;
  5411.         final_text   : type_text_line ;
  5412.         txt_to_move  : integer ;
  5413.         real_leading_spaces : type_leading_spaces ;
  5414.       begin -- add_start_of_line_to_copy_buffer
  5415.         determine_left_and_right ( in_first_col , in_last_col ) ;
  5416.         real_leading_spaces := lines_leading_spaces ;
  5417.         case right_place is
  5418.           when in_leading       => last_pos := 0 ;
  5419.                                    ln_length:= 0 ;
  5420.                                    if last_col > 0 then
  5421.                                      lines_leading_spaces := last_col ;
  5422.                                    end if ;
  5423.           when at_stuff_start   => last_pos := first_line_character_position ;
  5424.           when in_text          => last_pos := first_line_character_position 
  5425.                                                + last_col 
  5426.                                                - real_Leading_Spaces - 1 ;
  5427.           when at_text_end      
  5428.              | past_end_of_line => last_pos := last_line_character_position  ;
  5429.                                    last_col := lines_last_column ;
  5430.              -- sometime later we might want to include trailing spaces, and
  5431.              -- then in that case we would break these into two cases.....
  5432.         end case ;
  5433.         if last_pos > 0 then
  5434.           ln_length := last_pos - first_line_character_position + 1 ;
  5435.         end if ;
  5436.         if last_col > 0 then
  5437.           add_this_line ( lines_leading_spaces ,
  5438.                           first_line_character_position ,
  5439.                           last_pos ,
  5440.                           ln_length , false ) ;
  5441.         end if ;
  5442.         if should_delete_extra_leading
  5443.         -- means that the first line started at the beginning of a line
  5444.         and then lines_leading_spaces + 1 >= last_col then 
  5445.         -- means that the last line ends at the beginning of a line
  5446.           if delete_after_copy then
  5447.             delete_chunk ;
  5448.             if not cursor_backward_line then
  5449.               -- should always be able to move back, otherwise, the first and
  5450.               -- last lines are not fixed correctly....
  5451.               error(" Possibly Fatal Program Error: 1 " ,
  5452.                     not_fatal_error ,operator_wait ,short_beep ) ;
  5453.               -- here, failed to delete the first line of the deletion....
  5454.             else
  5455.               fix_fixed_cursor ;
  5456.               first_deleted_position := which_buffer.fixed_cursor.line_start ;
  5457.               last_deleted_position := last_line_character_position + 1 ;
  5458.               delete_chunk ;  -- gets rid of first line of deletion...
  5459.             end if ;
  5460.             which_buffer.fixed_cursor.file_line_number := orig_line_number ;
  5461.             original_location.column := 0 ;
  5462.           end if ;
  5463.           return ; -- because we don't need to do anything on a last line...
  5464.         end if ;
  5465.         If delete_after_copy then
  5466.           get_text_line( which_buffer , which_buffer.fixed_cursor.line_start ,
  5467.                      final_text ) ;
  5468.           last_deleted_position := last_line_character_position + 1 ;
  5469.           delete_chunk ; -- got rid of that line.....
  5470.           -- now, merge first and last lines...
  5471.           -- go backward one line...
  5472.           if not cursor_backward_line then
  5473.             -- should always be able to move back, otherwise, the first and
  5474.             -- last lines are not fixed correctly....
  5475.             error(" Possibly Fatal Program Error: 1 " ,
  5476.                   not_fatal_error ,operator_wait ,short_beep ) ;
  5477.             -- here, the line where the deletion started is still in the
  5478.             -- buffer, but the entire line where the deletion stopped is
  5479.             -- lost forever.....
  5480.           else
  5481.             txt_to_move := final_text.data_length - last_col ;
  5482.             if txt_to_move > 0 then
  5483.               for pn in 1 .. txt_to_move loop
  5484.                 orig_text.data( orig_text.data_length + pn ) 
  5485.                             := final_text.data( last_col + pn ) ;
  5486.               end loop ;
  5487.               orig_text.data_length := orig_text.data_length + txt_to_move ;
  5488.             end if ;
  5489.             -- replace the first line no matter what....
  5490.             replace_current_text ( orig_text ) ;
  5491.             which_buffer.fixed_cursor.file_line_number := orig_line_number ;
  5492.           end if ;
  5493.         end if ; -- delete after copy 
  5494.       end add_start_of_line_to_copy_buffer ;
  5495.        
  5496.       function special_cursor_forward_line ( FirstLn : boolean := false ) 
  5497.                               return boolean is 
  5498.         -- a merging of cursor_forward_line and line_forward for speed...
  5499.         ending_position : type_buffer_position ;
  5500.         successfull     : boolean              ;
  5501.         pn              : type_buffer_position ;
  5502.       begin -- special_cursor_forward_line 
  5503.         if which_buffer.fixed_cursor.line_start + max_bytes_in_line
  5504.               >= which_buffer.bufcount - max_bytes_in_line then
  5505.           delete_chunk ;
  5506.           pop_data( which_buffer , thebot , successfull ) ;
  5507.           first_deleted_position := which_buffer.fixed_cursor.line_start ;
  5508.           last_deleted_position := first_deleted_position - 1 ;
  5509.           if not successfull then
  5510.             return false ;
  5511.           else
  5512.             -- we are here because we have deleted the chunk of text from 
  5513.             -- memory, and have at the same time managed to move forward
  5514.             -- a line if we deleted after the copy.........
  5515.             if delete_after_copy and ( not firstln ) then
  5516.               -- delete first_deleted_position .. last_deleted_position ...
  5517.               -- simply, find out if we are at the end of the buffer...
  5518.               -- here, we may need to put back the 0 0 0 ....
  5519.               if which_buffer.e_buf(first_deleted_position).data 
  5520.                                       = buffer_boundry then
  5521.                 -- we must put back the empty last line...
  5522.                 pn := first_deleted_position ;
  5523.                 -- The following copied from buffer package.....
  5524.                 which_buffer.e_buf(pn  ).data := extended_character(  0)     ;
  5525.                 which_buffer.e_buf(pn+1).data := extended_character(  0)     ;
  5526.                 which_buffer.e_buf(pn+2).data := extended_character(  0)     ;
  5527.                 which_buffer.e_buf(pn+3).data
  5528.                                            :=extended_character(buffer_boundry);
  5529.                 which_buffer.bufcount         := pn + 3 ;
  5530.                 return false ;
  5531.               else
  5532.                 which_buffer.fixed_cursor.file_line_number 
  5533.                           := which_buffer.fixed_cursor.file_line_number + 1 ;
  5534.                 return true ;
  5535.               end if ;
  5536.             end if ;
  5537.           end if ;
  5538.         end if ;
  5539.         ending_position :=
  5540.               which_buffer.fixed_cursor.line_start + line_length(
  5541.                   which_buffer , which_buffer.fixed_cursor.line_start ) + 3 ;
  5542.         if which_buffer.e_buf(ending_position).data = buffer_boundry then
  5543.           return false ;
  5544.         else
  5545.           which_buffer.moving_cursor.line_start := ending_position ;
  5546.           which_buffer.moving_cursor.file_line_number :=
  5547.                   which_buffer.fixed_cursor.file_line_number + 1 ;
  5548.           which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  5549.           return true ;
  5550.         end if;
  5551.       end special_cursor_forward_line ;
  5552.  
  5553.     begin -- Copy_Text_To_Copy_Buffer
  5554.       copy_out_initialize;
  5555.       -- now, we need to move (and delete if asked) to second_pos
  5556.       orig_line_number := which_buffer.fixed_cursor.file_line_number ;
  5557.       get_text_line( which_buffer , which_buffer.fixed_cursor.line_start ,
  5558.                      orig_text ) ;
  5559.       if first_pos.line = second_pos.line then
  5560.         -- only a partial line...
  5561.         add_partial_line_to_copy_buffer( first_pos.column, second_pos.column );
  5562.       else
  5563.         orig_col := which_buffer.fixed_cursor.column_offset ;
  5564.         add_end_of_line_to_copy_buffer( first_pos.column ) ;
  5565.         -- that sends back the first_pos.column which was worked on...
  5566.         if first_pos.column > 0 then
  5567.           -- zero means at end of line...
  5568.           orig_col := first_pos.column ;
  5569.           orig_text.data_length := orig_col - 1 ;
  5570.         end if ;
  5571.         -- note that the first line is not worked with....
  5572.         if special_cursor_forward_line ( true ) then
  5573.           first_deleted_position := which_buffer.fixed_cursor.line_start ;
  5574.           last_deleted_position := first_deleted_position - 1 ;
  5575.           loop
  5576.           exit when which_buffer.fixed_cursor.file_line_number 
  5577.                                                               = second_pos.line;
  5578.             add_line_to_copy_buffer ;
  5579.             if delete_after_copy then
  5580.               last_deleted_position := last_line_character_position + 1 ;
  5581.             end if ;
  5582.           exit when not special_cursor_forward_line ;
  5583.           end loop ;
  5584.           delete_chunk ;
  5585.           if which_buffer.fixed_cursor.file_line_number = second_pos.line then
  5586.             add_start_of_line_to_copy_buffer( second_pos.column ) ;
  5587.             -- which merges in the orig info.....
  5588.           end if ;
  5589.         end if ;
  5590.       end if ;
  5591.       Current_Copy_Data.Present_Copy_Length := next_copy_position ;
  5592.       which_buffer.fixed_cursor.buffer_position := 0 ;
  5593.       which_buffer.fixed_cursor.column_offset   := 0 ;
  5594.       jump_to_position ( which_buffer , Original_Location.line ,
  5595.                                         Original_Location.column ,
  5596.                                         false ) ;
  5597.       copy_out_finish ;
  5598.     exception
  5599.       when no_room_to_copy_text => 
  5600.                               Current_Copy_Data.Present_Copy_Length 
  5601.                                                        := next_copy_position ;
  5602.                               which_buffer.fixed_cursor.buffer_position := 0 ;
  5603.                               which_buffer.fixed_cursor.column_offset   := 0 ;
  5604.                               copy_out_finish ;
  5605.     end Copy_Text_To_Copy_Buffer ;
  5606.       
  5607.     procedure Copy_Text_Back_From_Copy_Buffer ( which_buffer :
  5608.                                                   in out an_editor_buffer ) is
  5609.       orig_text : type_text_line ;
  5610.       orig_col  : column_position ;
  5611.       orig_lead : column_position ;
  5612.       new_text  : type_text_line ;
  5613.       cblock : block ;
  5614.       ok       : boolean ;
  5615.       buffer_is_open : boolean := false ;
  5616.       failed_copy : boolean := false ;
  5617.       no_room_to_copy_text : exception ;
  5618.       last_out_char_was_dle : boolean := false ;
  5619.       orig_line_number : line_number ;
  5620.       copy_in_started_at_stuff_start : boolean ;
  5621.       delete_first_spaces : boolean ;
  5622.       delete_next_spaces : boolean ;
  5623.       actual_copy_range : text_range ;
  5624.      
  5625.       procedure open_for_copy is
  5626.         -- special open based upon first items in copy block
  5627.         nxt_line_start : type_buffer_position ;
  5628.         leading    : type_leading_spaces ;
  5629.         text_first ,
  5630.         text_last  : type_text_length    ;
  5631.         text_leng  : type_line_length    ;
  5632.       begin -- open_for_copy
  5633.         orig_line_number := which_buffer.fixed_cursor.file_line_number ;
  5634.         get_text_line( which_buffer , which_buffer.fixed_cursor.line_start ,
  5635.                        orig_text ) ;
  5636.         -- the following in case the col is past the right edge of text line
  5637.         for posn in orig_text.data_length + 1 .. max_column_number loop
  5638.           orig_text.data(posn) := extended_character(32); -- spaces...
  5639.         end loop ;
  5640.         orig_col := which_buffer.fixed_cursor.column_offset ;
  5641.         new_text := orig_text ;
  5642.         new_text.data_length := orig_col - 1 ;
  5643.         -- now, work on buffer
  5644.         get_leading( orig_text , leading , text_first , text_last , text_leng );
  5645.         orig_lead := leading ;
  5646.         nxt_line_start := which_buffer.fixed_cursor.line_start 
  5647.                           + text_leng + 3 ;
  5648.         open_buffer( which_buffer , nxt_line_start , 
  5649.                                      block_size + max_bytes_in_line ) ;
  5650.         -- and delete current line...
  5651.         which_buffer.first_open_position 
  5652.                := which_buffer.fixed_cursor.line_start ;
  5653.         --
  5654.         buffer_is_open := true ;
  5655.         copy_in_started_at_stuff_start := text_leng = 0 
  5656.                                   or else orig_col <= leading + 1 ;
  5657.         if Current_Copy_Data.Copy_Started_At_Stuff_Start then
  5658.           -- must check for deleting the line prior to this....
  5659.           delete_next_spaces  := true ;
  5660.           if copy_in_started_at_stuff_start then
  5661.             -- here we should move back some spaces....
  5662.             new_text.data_length := 0 ;
  5663.             orig_col := 1 ;
  5664.             delete_first_spaces := false ;
  5665.           else
  5666.             -- we should skip the leading spaces because we are inside a line
  5667.             delete_first_spaces := true ;
  5668.           end if ;
  5669.         else
  5670.           delete_first_spaces := false ; -- we didn't start at a new line...
  5671.         end if ;
  5672.       end open_for_copy ;
  5673.        
  5674.       procedure replace_current_text ( also_save_this_many :
  5675.                                            integer := max_bytes_in_line + 2 ) is
  5676.         -- the two are to ensure that we have some empty space in the
  5677.         -- buffer on the last line.....
  5678.         leading    : type_leading_spaces ;
  5679.         text_first ,
  5680.         text_last  : type_text_length    ;
  5681.         text_leng  : type_line_length    ;
  5682.         old_leng   : type_line_length ;
  5683.         ln_start   : type_buffer_position ;
  5684.         new_nxt_line : type_buffer_position ;
  5685.         successfull  : boolean ;
  5686.       begin -- replace_current_text 
  5687.         get_leading ( new_text, leading , text_first , text_last , text_leng ) ;
  5688.         ln_start := which_buffer.fixed_cursor.line_start ;
  5689.         if ln_start + text_leng + 3 + also_save_this_many
  5690.                                          >= which_buffer.last_open_position then
  5691.           -- need to push some data around.......
  5692.           -- we have to ensure that we have enough room for both this line
  5693.           -- and any final line which might be around.....
  5694.           which_buffer.first_open_position := ln_start ;
  5695.           if ln_start > block_size then
  5696.             push_data( which_buffer , thetop , successfull ) ;
  5697.           else
  5698.             push_data( which_buffer , thebot , successfull ) ;
  5699.           end if ;
  5700.           if not successfull then
  5701.             error( "Unable to Add Copy Text. No Temporary File Room.",
  5702.                    not_fatal_error , operator_wait , short_beep ) ;
  5703.             raise no_room_to_copy_text ;
  5704.           else
  5705.             ln_start := which_buffer.fixed_cursor.line_start ;
  5706.           end if ;
  5707.         end if ;
  5708.         -- guaranteed to have some room available...
  5709.         new_nxt_line := ln_start + text_leng + 3 ;
  5710.         which_buffer.e_buf(ln_start).data    
  5711.                                 := extended_character(text_leng) ;
  5712.         which_buffer.e_buf(ln_start+1 ).data 
  5713.                                 := extended_character(leading) ;
  5714.         for place in 1 .. text_leng loop
  5715.           which_buffer.e_buf(ln_start + 1 + place ).data :=
  5716.                         new_text.data(text_first+place-1) ;
  5717.         end loop ;
  5718.         which_buffer.e_buf(ln_start + text_leng + 2 ).data 
  5719.                                 := extended_character(text_leng) ;
  5720.         for place in ln_start .. ln_start + text_leng + 2 loop
  5721.           which_buffer.e_buf(place).attr := no_screen_attribute ;
  5722.         end loop ;
  5723.         which_buffer.fixed_cursor.line_start :=ln_start + text_leng + 3 ;
  5724.         which_buffer.fixed_cursor.file_line_number
  5725.                         := which_buffer.fixed_cursor.file_line_number + 1 ;
  5726.         new_text.data_length := 0 ;
  5727.         which_buffer.first_open_position :=which_buffer.fixed_cursor.line_start;
  5728.       end replace_current_text ;
  5729.         
  5730.       procedure add_in_new_character ( c : extended_character ) is
  5731.         spaces_out : integer := 0 ;
  5732.       begin -- add_in_new_character 
  5733.         if last_out_char_was_dle then
  5734.           -- this is a blank compression code
  5735.           if delete_first_spaces then
  5736.             -- here if we had an old set of spaces at the beginning of 
  5737.             -- a copy ...
  5738.             delete_first_spaces := false ;
  5739.           else
  5740.             spaces_out := integer(c);
  5741.             loop
  5742.             exit when new_text.data_length = max_column_number ;
  5743.             exit when spaces_out < 1 ;  -- in the case of <dle><0>....
  5744.               new_text.data_length := new_text.data_length + 1 ;
  5745.               new_text.data( new_text.data_length ) 
  5746.                   := extended_character( character'pos( ' ' ) ) ;
  5747.               spaces_out := spaces_out - 1 ;
  5748.             end loop ;
  5749.           end if ;
  5750.           last_out_char_was_dle := false ;
  5751.         elsif c = extended_character( character'pos( ascii.cr ) ) then
  5752.           -- this is the end of a line.....
  5753.           delete_first_spaces := false ;
  5754.           replace_current_text ;
  5755.         elsif c = extended_character( character'pos( ascii.dle) ) then
  5756.           last_out_char_was_dle := true ;
  5757.         else
  5758.           -- just a normal output character ...
  5759.           delete_first_spaces := false ;
  5760.           if new_text.data_length < max_column_number then
  5761.             -- we can add a new character
  5762.             new_text.data_length := new_text.data_length + 1 ;
  5763.             new_text.data( new_text.data_length ) := c ;
  5764.           -- else we ignore.....might later give an error message
  5765.           end if ;
  5766.         end if ;
  5767.       end add_in_new_character ;
  5768.        
  5769.       procedure merge_block ( first_loc , last_loc : block_offset ) is
  5770.       begin -- merge_block
  5771.         -- merge in data from cblock...
  5772.         for posn in first_loc .. last_loc loop
  5773.           add_in_new_character( cblock( posn ).data ) ;
  5774.           -- note that any attributes are lost here......
  5775.         end loop ;
  5776.       end merge_block ;
  5777.        
  5778.       procedure close_for_copy is
  5779.         -- here, we must take New_Text.Data from 1 .. New_Text.Data_Length
  5780.         -- as the final line which is to be input.... To that, we must
  5781.         -- append Orig_Text.Data from Orig_Col .. Orig_Text.Data_Length 
  5782.         -- however, if failed_copy....don't try to push it.....
  5783.         -- otherwise, we might try to raise no_room_to_copy_text....
  5784.         -- note that if we have not yet failed, then the replace...(0)
  5785.         -- cannot fail!!!
  5786.         leading    : type_leading_spaces ;
  5787.         text_first ,
  5788.         text_last  : type_text_length    ;
  5789.         text_leng  : type_line_length    ;
  5790.         last_col   : column_position ;
  5791.       begin -- close_for_copy 
  5792.         last_out_char_was_dle := false ;
  5793.         -- that was done just in case...however, that should NEVER have been
  5794.         -- set to true when this close is called.......except possibly if
  5795.         -- an exception was raised....
  5796.         last_col := new_text.data_length ;
  5797.         if Current_Copy_Data.Copy_Started_At_Stuff_Start 
  5798.         and then Current_Copy_Data.Copy_Ended_At_Stuff_Start 
  5799.         and then copy_in_started_at_stuff_Start then
  5800.           -- we must insert the line without the ending leading spaces ...
  5801.           new_text.data_length := 0 ; -- eats the leading at the end...
  5802.         end if ;
  5803.         for posn in orig_col .. Orig_Text.Data_Length loop
  5804.           add_in_new_character( Orig_Text.Data(posn) ) ;
  5805.         end loop ;
  5806.         -- now, we must add in the new characters only if there is
  5807.         -- text there to do it to...
  5808.         get_leading ( new_text, leading , text_first , text_last , text_leng ) ;
  5809.         -- now, see what we should do..
  5810.         if text_leng = 0 then
  5811.           -- ok, there is nothing here to add in.....
  5812.           if orig_line_number = which_buffer.fixed_cursor.file_line_number then
  5813.             -- ok, if we just added spaces....then add them in...
  5814.             replace_current_text(0);
  5815.           else
  5816.             -- else, if we added at least a line, and now have nothing, throw
  5817.             -- the remainder away....
  5818.             -- last_col := 0 ;
  5819.             --
  5820.             --  that didn't seem right, here we just replace it...
  5821.             replace_current_text(0);
  5822.           end if ;
  5823.         else
  5824.           -- ok, there is something here to add in ...
  5825.           replace_current_text(0);
  5826.         end if ;
  5827.         which_buffer.first_open_position :=which_buffer.fixed_cursor.line_start;
  5828.         close_buffer( which_buffer ) ;
  5829.         actual_copy_range.lo_position := ( orig_line_number , orig_col ,
  5830.                                            no_screen_attribute , which_buffer );
  5831.         actual_copy_range.hi_position := ( which_buffer.fixed_cursor
  5832.                                              .file_line_number , last_col ,
  5833.                                            no_screen_attribute , which_buffer );
  5834.         markers.marker_manager.update_markers_for_added_text(
  5835.                                     which_buffer , actual_copy_range ) ;
  5836.       end close_for_copy ;
  5837.        
  5838.       procedure copy_in_finish is
  5839.       begin -- copy_in_finish
  5840.         -- must move to the correct location and show the screen
  5841.         which_buffer.fixed_cursor.buffer_position := 0 ;
  5842.         which_buffer.fixed_cursor.column_offset   := 0 ;
  5843.         jump_to_position ( which_buffer , orig_line_number , orig_col , false );
  5844.         if copy_in_started_at_stuff_start then
  5845.           which_buffer.fixed_cursor.column_offset      :=
  5846.                num_leading_spaces(which_buffer,
  5847.                                   which_buffer.fixed_cursor.line_start ) + 1 ;
  5848.         end if ;
  5849.         show_screen( which_buffer ) ;
  5850.                       -- , which_buffer.fixed_cursor , orig_screen_line ) ;
  5851.       end copy_in_finish ;
  5852.        
  5853.     begin -- Copy_Text_Back_From_Copy_Buffer
  5854.       if not current_copy_data.we_have_copy_data then
  5855.         error(" No Copy Buffer Data... " ,
  5856.               not_fatal_error , operator_wait , short_beep ) ;
  5857.       else
  5858.         for block_number in 1 .. Current_Copy_Data.Present_Copy_Block loop 
  5859.           getblock( cblock , block_number , ok ) ;
  5860.           if not ok then
  5861.             error(" Unable to correctly read temporary copy file. " ,
  5862.                   not_fatal_error , operator_wait , short_beep ) ;
  5863.             return ;
  5864.           else
  5865.             if not buffer_is_open then
  5866.               open_for_copy ;
  5867.             end if ;
  5868.             merge_block ( 0 , block_offset'last ) ;
  5869.           end if ;
  5870.         end loop ;
  5871.         if Current_Copy_Data.Present_Copy_Length > 0 then
  5872.           if not buffer_is_open then
  5873.             open_for_copy ;
  5874.           end if ;
  5875.           cblock := Current_Copy_Data.The_Copy_Buffer ;
  5876.           merge_block( 0, Current_Copy_Data.Present_Copy_Length - 1 );
  5877.         end if ;
  5878.         if buffer_is_open then
  5879.           close_for_copy ;
  5880.         end if ;
  5881.         copy_in_finish ;
  5882.       end if ;
  5883.     exception
  5884.       when no_room_to_copy_text => failed_copy := true ;
  5885.                                    if buffer_is_open then
  5886.                                      close_for_copy ;
  5887.                                    end if ;
  5888.                                    copy_in_finish ;
  5889.     end Copy_Text_Back_From_Copy_Buffer ;
  5890.        
  5891.     begin -- copy_package
  5892.       The_Copy_Data := new Type_Copy_Data ;
  5893.       Current_Copy_Data := The_Copy_Data ;
  5894.       initialize_copy_package ;
  5895.     end copy_package ;
  5896.    
  5897.     procedure store_reverse ( new_reverse : boolean ) is
  5898.     begin -- store_reverse 
  5899.       reverse_storage := current_reverse ;
  5900.       if reverse_storage /= new_reverse then
  5901.         set_reverse( new_reverse ) ;
  5902.       end if ;
  5903.     end store_reverse ;
  5904.       
  5905.     procedure restore_reverse is
  5906.     begin -- restore_reverse
  5907.       set_reverse_if_necessary ( reverse_storage ) ;
  5908.     end restore_reverse ;
  5909.       
  5910.     procedure set_direction ( go_forward : boolean ) is
  5911.       -- Set the direction arrow at the top left corner
  5912.     begin -- set_direction 
  5913.       store_reverse ( false )  ;
  5914.       is_go_forward := go_forward ;
  5915.       goto_prompt_line_column( master_buffer , 1 , 1 ) ;
  5916.       if go_forward then
  5917.         put('>');
  5918.       else
  5919.         put('<');
  5920.       end if ;
  5921.       restore_reverse ;
  5922.       show_cursor;
  5923.     end set_direction ;
  5924.       
  5925.     procedure show_repeat ( repeat_factor : a_repeat_factor ) is
  5926.       temp_string : string_library.pstring ;
  5927.     begin -- show_repeat
  5928.       last_repeat := repeat_factor ;
  5929.       if repeat_factor < 0 then
  5930.         -- code for once
  5931.         repeat_prompt := string_to_pstring("[ Once]");
  5932.       elsif repeat_factor = infinity then
  5933.         repeat_prompt := string_to_pstring("[Every]");
  5934.       else
  5935.         temp_string := int_to_str( repeat_factor ) ;
  5936.         while length(temp_string) < 5 loop
  5937.           temp_string := " " & temp_string ;
  5938.         end loop ;
  5939.         repeat_prompt := "[" & temp_string & "]" ;
  5940.       end if ;
  5941.       store_reverse ( false )  ;
  5942.       goto_prompt_line_column( master_buffer , 1 , 2 ) ;
  5943.       put(repeat_prompt);
  5944.       restore_reverse ;
  5945.     end show_repeat ;
  5946.       
  5947.     procedure set_repeat_prompt( is_show_repeat_on : boolean ;
  5948.                                  repeat_factor     : a_repeat_factor ) is
  5949.       -- If is_show_repeat_on, the set the repeat factor string
  5950.       -- as stated in repeat_factor.  If it is -1, then set it
  5951.       -- as [Once].  
  5952.     begin -- set_repeat_prompt
  5953.       if not is_show_repeat_on then
  5954.         repeat_prompt := string_library.blank_line ;
  5955.       else
  5956.         -- we are showing the repeat factor 
  5957.         show_repeat( repeat_factor ) ;
  5958.         show_cursor;
  5959.       end if ;
  5960.     end set_repeat_prompt ;
  5961.         
  5962.     procedure prompt ( prompt_string : in string ) is
  5963.       -- show the prompt string in the master buffer
  5964.       -- >[Every] 
  5965.       -- 123456789
  5966.       line_posn : integer ;
  5967.     begin -- prompt 
  5968.       prompt_line := string_library.string_to_pstring( prompt_string ) ;
  5969.       store_reverse ( false )  ;
  5970.       if repeat_prompt /= string_library.blank_line then
  5971.         line_posn := 9 ;
  5972.       else
  5973.         line_posn := 1 ;
  5974.       end if ;
  5975.       clear_prompt_end_of_line( master_buffer , 1 , line_posn ) ;
  5976.       goto_prompt_line_column ( master_buffer , 1 , line_posn ) ;
  5977.       for posn in 1 .. length( prompt_line ) loop
  5978.         if prompt_line.data(posn) = '{' then
  5979.           -- to reverse
  5980.           set_reverse(true);
  5981.         elsif prompt_line.data(posn) = '}' then
  5982.           -- from reverse 
  5983.           set_reverse(false);
  5984.         else
  5985.           put( prompt_line.data(posn) );
  5986.         end if ;
  5987.       end loop ;
  5988.       restore_reverse ;
  5989.     end prompt ;
  5990.         
  5991.     procedure set_cursor( which_buffer : in out an_editor_buffer ;
  5992.                           cursor : in out cursor_position ;
  5993.                           linestart : in type_buffer_position ;
  5994.                           line   : in line_number         ; 
  5995.                           col    : in column_position   ) is
  5996.       -- set the cursor within which_buffer at the specified line and col
  5997.       -- note that if the col is not within the text area, then the
  5998.       -- cursor's buffer_position is 0.
  5999.       -- if col is sent as 0 , then move to the first text position on line
  6000.       the_leading_spaces : type_leading_spaces ;
  6001.       target_col         : column_position     ;
  6002.       last_col           : column_position     ; 
  6003.     begin -- set_cursor 
  6004.       the_leading_spaces := num_leading_spaces(which_buffer,linestart);
  6005.       last_col           := the_leading_spaces 
  6006.                                 + line_length(which_buffer,linestart);
  6007.       if col = 0 then
  6008.         -- we want to go to the first text on line
  6009.         target_col       := the_leading_spaces + 1 ;
  6010.       else
  6011.         target_col       := col ;
  6012.       end if ;
  6013.       if target_col <= the_leading_spaces then
  6014.         cursor.buffer_position := 0 ; -- not specified 
  6015.       elsif target_col > last_col then
  6016.         cursor.buffer_position := 0 ; -- Past right end
  6017.       else
  6018.         cursor.buffer_position := linestart + target_col 
  6019.                                             - the_leading_spaces + 1 ;
  6020.         -- the + 1 is for skipping the <leading-spaces> position
  6021.       end if ;
  6022.       cursor.file_line_number:= line      ;
  6023.       cursor.line_start      := linestart ;
  6024.       cursor.column_offset   := target_col;
  6025.     end set_cursor ;
  6026.   
  6027.     procedure just_show_screen( which_buffer : in out an_editor_buffer ) is
  6028.                -- Given the current screen definition, show the entire 
  6029.                -- screen within the current window.
  6030.                -- only called when we know we are on the screen
  6031.                -- don't worry about cursor
  6032.       starting_position : type_buffer_position ;
  6033.       current_window_line ,
  6034.       last_window_line    : window_line_number ;
  6035.       current_line_number : line_number ;
  6036.     begin -- just_show_screen 
  6037.       which_buffer.floating_cursor := which_buffer.fixed_cursor ;
  6038.       which_buffer.fixed_cursor    := which_buffer.top_screen_cursor ;
  6039.       current_line_number          := which_buffer.top_screen_cursor
  6040.                                            .file_line_number ;
  6041.       current_window_line := 1 ;
  6042.       last_window_line    := window_height(which_buffer);
  6043.          
  6044.       clear_window( which_buffer ) ;
  6045.       loop
  6046.         starting_position := which_buffer.fixed_cursor.line_start ;
  6047.         show_line( which_buffer , starting_position , current_line_number ) ;
  6048.         line_forward( which_buffer );
  6049.       exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ;
  6050.         which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  6051.         current_line_number := current_line_number + 1 ;
  6052.         current_window_line := current_window_line + 1 ;
  6053.       exit when ( current_window_line > last_window_line )  ;
  6054.       end loop ;
  6055.       which_buffer.fixed_cursor := which_buffer.floating_cursor ;
  6056.     end just_show_screen ;
  6057.         
  6058.     procedure show_screen( which_buffer : in out an_editor_buffer ) is
  6059.                -- Given the current screen definition, show the entire 
  6060.                -- screen within the current window.
  6061.     begin -- show_screen 
  6062.       if not cursor_off_screen(which_buffer) then
  6063.         just_show_screen( which_buffer ) ;
  6064.       end if ;
  6065.       show_cursor(which_buffer);
  6066.     end show_screen ;
  6067.       
  6068.     procedure show_screen( which_buffer : in out an_editor_buffer ;
  6069.                            cursor       : in out cursor_position  ;
  6070.                            Cursor_Line  : in window_line_number   ) is
  6071.                -- Given the current screen definition, show the entire 
  6072.                -- screen within the current window.
  6073.                -- The cursor is to be put on cursor_line if possible.
  6074.                -- Note: cursor might be found as both CURSOR and
  6075.                -- WHICH_BUFFER.fixed_CURSOR
  6076.     begin -- show_screen 
  6077.       which_buffer.fixed_cursor := cursor ;
  6078.       memory_center( which_buffer , cursor_line ) ;
  6079.       if not cursor_off_screen(which_buffer) then
  6080.         just_show_screen( which_buffer ) ;
  6081.       -- else is caught in show_cursor...
  6082.       end if ;
  6083.       show_cursor( which_buffer ) ;
  6084.       cursor := which_buffer.fixed_cursor ;
  6085.     end show_screen ;
  6086.         
  6087.     procedure adjust_cursor_lines( which_buffer : in out an_editor_buffer ;
  6088.                                    number_of_lines : integer ) is
  6089.       old_position : type_buffer_position ;
  6090.     begin -- adjust_cursor_lines 
  6091.       if number_of_lines > 0 then
  6092.         -- we are moving forward ;
  6093.         set_cursor_down_lines( which_buffer                    ,
  6094.                                which_buffer.top_screen_cursor  ,
  6095.                                which_buffer.top_screen_cursor  ,
  6096.                                number_of_lines               ) ;
  6097.         set_cursor_down_lines( which_buffer                    ,
  6098.                                which_buffer.next_screen_cursor ,
  6099.                                which_buffer.next_screen_cursor ,
  6100.                                number_of_lines               ) ;
  6101.       else
  6102.         set_cursor_up_lines  ( which_buffer                    ,
  6103.                                which_buffer.top_screen_cursor  ,
  6104.                                which_buffer.top_screen_cursor  ,
  6105.                                - number_of_lines             ) ;
  6106.         set_cursor_down_lines( which_buffer                    ,
  6107.                                which_buffer.top_screen_cursor  ,
  6108.                                which_buffer.next_screen_cursor ,
  6109.                                window_height(which_buffer)   ) ;
  6110.       end if ;
  6111.     end adjust_cursor_lines ;
  6112.       
  6113.     procedure scroll_up ( which_buffer : in out an_editor_buffer ;
  6114.                           bottom_cursor: in cursor_position      ;
  6115.                           number_of_lines : integer              ) is
  6116.       -- bottom_line is the start of the next line to output 
  6117.       -- number_of_lines is the number to work with
  6118.       -- top_screen_cursor.line_start does not have to be set...
  6119.       old_line_number : line_number ;
  6120.       lines_moved     : integer     ;
  6121.     begin -- scroll_up
  6122.       which_buffer.floating_cursor := which_buffer.fixed_cursor ;
  6123.       old_line_number := bottom_cursor.file_line_number ;
  6124.       which_buffer.fixed_cursor := bottom_cursor ;
  6125.       -- First, put out the new lines
  6126.       lines_moved := 0 ;
  6127.       scroll_up_entire_window( number_of_lines ) ;
  6128.       while lines_moved < number_of_lines loop
  6129.         goto_line_column( which_buffer , window_height(which_buffer) 
  6130.                                          - number_of_lines + lines_moved + 1 , 
  6131.                                          lowest_column_number(which_buffer) ) ;
  6132.         show_line(which_buffer,which_buffer.fixed_cursor.line_start ,
  6133.                                                         old_line_number ,false);
  6134.         line_forward( which_buffer ) ;
  6135.       exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ;
  6136.         which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  6137.         lines_moved := lines_moved + 1 ;
  6138.         old_line_number := old_line_number + 1 ;
  6139.       end loop ;
  6140.       -- adjust assumes a good starting location for top/next screen cursors
  6141.       which_buffer.fixed_cursor := which_buffer.floating_cursor ;
  6142.       adjust_cursor_lines( which_buffer , number_of_lines ) ;
  6143.     end scroll_up ;
  6144.       
  6145.     procedure show_cursor is
  6146.       -- move the actual cursor to the position on the screen where the
  6147.       -- master buffer's logical cursor is
  6148.     begin -- show_cursor 
  6149.       show_cursor( master_buffer ) ;
  6150.     end show_cursor ;
  6151.         
  6152.     procedure show_cursor ( which_buffer : in out an_editor_buffer ) is
  6153.                -- Show the cursor on the screen.  If necessary, push/pop
  6154.                -- data to make sure you have enough for the entire screen
  6155.       new_line : window_line_number ;
  6156.       new_col  : window_column_number ;
  6157.       please_redo_screen : boolean := false ;
  6158.         
  6159.       procedure go_up_lines ( which_buffer : in out an_editor_buffer ;
  6160.                               number_of_lines : integer ) is
  6161.         -- add the appropriate number of lines to the beginning of the
  6162.         -- screen .
  6163.       begin -- go_up_lines 
  6164.         if please_redo_screen or else
  6165.            ( number_of_lines > window_height( which_buffer ) / 2 ) then
  6166.           -- just center the cursor
  6167.           memory_center ( which_buffer , window_height(which_buffer) / 2 ) ;
  6168.           -- Now that we have fixed it, show the screen
  6169.           just_show_screen( which_buffer ) ;
  6170.           please_redo_screen := false ;
  6171.         else
  6172.           -- we can add just a few????
  6173.           -- We might use insert if the crt has it........LATER!
  6174.           memory_center ( which_buffer , window_height(which_buffer) / 2 ) ;
  6175.           -- Now that we have fixed it, show the screen
  6176.           just_show_screen( which_buffer ) ;
  6177.         end if ;
  6178.       end go_up_lines ;
  6179.       
  6180.       procedure show_scroll ( which_buffer : in out an_editor_buffer ;
  6181.                               first_line_to_show ,
  6182.                               last_line_to_show : line_number       ) is
  6183.         save_cursor : cursor_position ; -- because we know that no
  6184.                                         -- disk access can take place
  6185.                                         -- during this procedure
  6186.       begin -- show_scroll
  6187.         -- save the current status
  6188.         save_cursor := which_buffer.fixed_cursor ;
  6189.         -- then, scroll the screen
  6190.         scroll_up_entire_window( last_line_to_show - first_line_to_show + 1 ) ;
  6191.         -- and then, display the text
  6192.         --     find the first line to work
  6193.         if which_buffer.next_screen_cursor.line_start = 0 then
  6194.           -- need to do it differently
  6195.           set_cursor_down_lines( which_buffer                    ,
  6196.                                  which_buffer.top_screen_cursor  ,
  6197.                                  which_buffer.moving_cursor      ,
  6198.                                  first_line_to_show 
  6199.                                  - which_buffer.top_screen_cursor
  6200.                                         .file_line_number      ) ;
  6201.         else
  6202.           set_cursor_up_lines ( which_buffer ,
  6203.                                 which_buffer.next_screen_cursor ,
  6204.                                 which_buffer.moving_cursor ,
  6205.                                 which_buffer.next_screen_cursor.file_line_number
  6206.                                 - first_line_to_show ) ; 
  6207.         end if ;
  6208.         which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  6209.         --    loop through, displaying the lines
  6210.         loop
  6211.           show_line(which_buffer,which_buffer.fixed_cursor.line_start,
  6212.                                  which_buffer.fixed_cursor.file_line_number ) ;
  6213.           line_forward( which_buffer ) ;
  6214.         exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ;
  6215.           which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  6216.         exit when which_buffer.fixed_cursor.file_line_number =
  6217.                   which_buffer.next_screen_cursor.file_line_number ;
  6218.         end loop ;
  6219.         which_buffer.fixed_cursor := save_cursor ;
  6220.       end show_scroll ;
  6221.         
  6222.       procedure go_down_lines ( which_buffer : in out an_editor_buffer ;
  6223.                                 number_of_lines : integer ) is
  6224.         -- place the appropriate number of lines at the end of the screen
  6225.         next_line_on_screen : line_number ;
  6226.       begin -- go_down_lines
  6227.         if please_redo_screen or else
  6228.            ( number_of_lines > window_height ( which_buffer ) ) then
  6229.           -- we need to redraw the screen
  6230.           memory_center ( which_buffer , window_height ( which_buffer ) / 2 );
  6231.           just_show_screen( which_buffer ) ;
  6232.           please_redo_screen := false ;
  6233.         else 
  6234.           -- just add lines
  6235.           next_line_on_screen := which_buffer.top_screen_cursor.file_line_number
  6236.                                  + window_height ( which_buffer ) ;
  6237.           -- show_buffer ( 'V' ) ;
  6238.           memory_center( which_buffer , window_height ( which_buffer ) ) ;
  6239.           -- show_buffer ( 'V' ) ;
  6240.           show_scroll ( which_buffer , next_line_on_screen ,
  6241.                                  which_buffer.fixed_cursor.file_line_number );
  6242.           -- show_buffer ( 'V' ) ;
  6243.         end if ;
  6244.       end go_down_lines ;
  6245.         
  6246.     begin -- show_cursor
  6247.       -- scroll as appropriate 
  6248.       if not cursor_off_screen(which_buffer) then
  6249.         -- that also sets top_screen_cursor.line_start if necessary 
  6250.         -- we get here with nothing to do..... still on screen 
  6251.         null ; -- not off screen . nothing to do
  6252.       else
  6253.         -- First, we will check horizontal 
  6254.         if which_buffer.fixed_cursor.column_offset
  6255.                             < lowest_column_number(which_buffer) then 
  6256.           -- the left screen position is protected by shift itself, 
  6257.           -- so there is no need to worry about going too far in one
  6258.           -- direction 
  6259.           shift( which_buffer , max ( 15 , lowest_column_number(which_buffer)
  6260.                                     - which_buffer.fixed_cursor.column_offset)
  6261.                                          + 5 ) ;
  6262.           -- Now that we have fixed it, show the screen
  6263.           please_redo_screen := true ;
  6264.         elsif which_buffer.fixed_cursor.column_offset
  6265.                             > highest_column_number(which_buffer) then
  6266.           shift( which_buffer,-max(15 , which_buffer.fixed_cursor.column_offset
  6267.                                        - highest_column_number(which_buffer)
  6268.                                        + 5 ));
  6269.           -- Now that we have fixed it, show the screen
  6270.           please_redo_screen := true ;
  6271.         end if ;
  6272.         -- Now, check vertical
  6273.         if which_buffer.top_screen_cursor.line_start = 0 then
  6274.           -- must show everything from scratch...
  6275.           memory_center ( which_buffer , window_height(which_buffer) / 2 ) ;
  6276.           -- Now that we have fixed it, show the screen
  6277.           just_show_screen( which_buffer ) ;
  6278.         elsif which_buffer.fixed_cursor.file_line_number 
  6279.                          < which_buffer.top_screen_cursor.file_line_number then
  6280.           -- we have to add lines to the top of the screen
  6281.           go_up_lines( which_buffer , 
  6282.                        which_buffer.top_screen_cursor.file_line_number 
  6283.                        - which_buffer.fixed_cursor.file_line_number ) ;
  6284.         elsif which_buffer.fixed_cursor.file_line_number 
  6285.                        > which_buffer.top_screen_cursor.file_line_number 
  6286.                                    + window_height(which_buffer)
  6287.                                    - 1 then
  6288.           go_down_lines(which_buffer, which_buffer.fixed_cursor.file_line_number
  6289.                              - which_buffer.top_screen_cursor.file_line_number
  6290.                              - window_height(which_buffer) + 1 ) ;
  6291.         else
  6292.           -- we had horizontal but not vertical
  6293.           -- don't even need to check please_redo_screen...
  6294.           just_show_screen( which_buffer ) ;
  6295.         end if ;
  6296.       end if ;
  6297.       -- now place the cursor where it should be
  6298.       new_line := which_buffer.fixed_cursor.file_line_number 
  6299.                         - which_buffer.top_screen_cursor.file_line_number + 1 ;
  6300.       new_col  := which_buffer.fixed_cursor.column_offset ;
  6301.       goto_line_column( which_buffer , new_line , new_col ) ;
  6302.     end show_cursor ;
  6303.       
  6304.     procedure jump_to_position ( which_buffer     : in out an_editor_buffer ;
  6305.                                  to_line_number   : in line_number          ;
  6306.                                  to_column_number : in column_position      ;
  6307.                                  show_new_position: in boolean := true    ) is
  6308.                -- Move the cursor and screen display to the specified
  6309.                -- position.  
  6310.       line             : line_number          ;
  6311.       target_column    : column_position      ;
  6312.     begin -- jump_to_position 
  6313.       target_column    := to_column_number    ;
  6314.       line   := which_buffer.fixed_cursor.file_line_number ;
  6315.       if to_line_number > line then
  6316.         -- We need to move forward 
  6317.         loop
  6318.           line_forward(which_buffer);
  6319.         exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ; 
  6320.           -- end of file
  6321.           which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  6322.           line   := line + 1   ;
  6323.         exit when line = to_line_number ; -- found line 
  6324.         end loop ;
  6325.         -- Here on either found line or at end of file
  6326.       elsif to_line_number < line then 
  6327.         -- We need to move backward 
  6328.         loop
  6329.           line_backward(which_buffer);
  6330.         exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ; 
  6331.           -- end of file
  6332.           which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  6333.           line   := line - 1   ;
  6334.         exit when line = to_line_number ; -- found line 
  6335.         end loop ;
  6336.         -- Here on either found line or at end of file
  6337.       end if ;
  6338.       -- Now, we need to move to the specified offset
  6339.       -- Line is current file line number
  6340.       -- Offset is current line start
  6341.       if line /= to_line_number then
  6342.         target_column := 0 ; -- Just go to first char on line
  6343.       end if;
  6344.       -- show_buffer ( 'V' ) ;
  6345.       -- Target column is the column to go to.  If = 0 , then go to
  6346.       -- the first text position on the line
  6347.       set_cursor(which_buffer,which_buffer.fixed_cursor,
  6348.                               which_buffer.fixed_cursor.line_start ,
  6349.                               which_buffer.fixed_cursor.file_line_number ,
  6350.                               target_column);
  6351.       if line /= to_line_number then
  6352.         -- we really need to go to the last character on the line
  6353.         which_buffer.fixed_cursor.column_offset := 
  6354.                     which_buffer.fixed_cursor.column_offset 
  6355.                     + line_length( which_buffer , 
  6356.                                    which_buffer.fixed_cursor.line_start ) ;
  6357.         which_buffer.fixed_cursor.buffer_position := 0 ;
  6358.       end if ;
  6359.       if show_new_position then
  6360.         show_screen ( which_buffer , which_buffer.fixed_cursor , 0 ) ;
  6361.       end if ;
  6362.     end jump_to_position ;
  6363.       
  6364.     function current_position return text_position is
  6365.     begin -- current_position
  6366.       return text_position'( current_buffer.fixed_cursor.file_line_number ,
  6367.                              current_buffer.fixed_cursor.column_offset    ,
  6368.                              no_screen_attribute , 
  6369.                              current_buffer);
  6370.     end current_position ;
  6371.   
  6372.     function cursor_forward_line return boolean is 
  6373.       -- return true if we moved forward a line like we were asked
  6374.     begin -- cursor_forward_line 
  6375.       line_forward( master_buffer ) ;
  6376.       if master_buffer.fixed_cursor = master_buffer.moving_cursor then
  6377.         -- we didn't move
  6378.         return false ;
  6379.       else
  6380.         -- we moved...
  6381.         master_buffer.fixed_cursor := master_buffer.moving_cursor ;
  6382.         return true ;
  6383.       end if ;
  6384.     end cursor_forward_line ;
  6385.   
  6386.     function cursor_backward_line return boolean is 
  6387.       -- return true if we moved backward a line like we were asked
  6388.     begin -- cursor_backward_line 
  6389.       line_backward( master_buffer ) ;
  6390.       if master_buffer.fixed_cursor = master_buffer.moving_cursor then
  6391.         -- we didn't move
  6392.         return false ;
  6393.       else
  6394.         -- we moved...
  6395.         master_buffer.fixed_cursor := master_buffer.moving_cursor ;
  6396.         return true ;
  6397.       end if ;
  6398.     end cursor_backward_line ;
  6399.   
  6400.     procedure get_leading ( txt : in out type_text_line ;
  6401.                             leading_spaces : out type_leading_spaces  ;
  6402.                             first_text_position,
  6403.                             last_text_position:out type_text_length ;
  6404.                             length : out type_line_length  ) is
  6405.       -- take a txt line and get facts necessary for insertion into
  6406.       -- the buffer.  truncate any values necessary to force it to
  6407.       -- be a valid line...
  6408.       leading , text_first , text_last , text_leng : integer ;
  6409.       -- because we error check after assigning values 
  6410.     begin -- get_leading 
  6411.       text_first := 1 ;
  6412.       while ( text_first <= txt.data_length ) 
  6413.       and then ( txt.data(text_first) = extended_character(32) ) loop 
  6414.         text_first := text_first + 1 ;
  6415.       end loop ;
  6416.       leading    := text_first - 1 ;
  6417.       text_last  := txt.data_length ;
  6418.       text_leng  := text_last - text_first + 1 ; 
  6419.       if text_leng > type_line_length'last then
  6420.         text_leng := type_line_length'last;
  6421.         text_last := text_first + text_leng - 1 ;
  6422.       end if ;
  6423.       if leading > type_leading_spaces'last then
  6424.         leading := type_leading_spaces'last ;
  6425.       end if ;
  6426.       txt.leading_spaces := leading ;
  6427.       leading_spaces       := leading    ;
  6428.       first_text_position  := text_first ;
  6429.       last_text_position   := text_last  ;
  6430.       length               := text_leng  ;
  6431.     end get_leading ;
  6432.      
  6433.     procedure get_next_command( Old_Repeat : in  a_repeat_factor ;
  6434.                                 New_Repeat : out a_repeat_factor ;
  6435.                                 new_command : out an_editor_command ) is 
  6436.       main_prompt_on : boolean := true ;
  6437.       TmpCmd : an_editor_command ;
  6438.       redo_once : boolean ;
  6439.       Tmp_New_Repeat : a_repeat_factor ;
  6440.        
  6441.       procedure get_repeat_factor_and_command is
  6442.         n: INTEGER;
  6443.         overflow: BOOLEAN;
  6444.         ch : character ;
  6445.         new_num : integer ; 
  6446.       begin 
  6447.         crt_windows.get_character ( ch , TmpCmd ) ;
  6448.         case TmpCmd is
  6449.           when infinity_command =>
  6450.                           set_repeat_prompt( true , infinity );
  6451.                           Tmp_New_Repeat := infinity ;
  6452.                           redo_once := true ;
  6453.           when digit_command    =>
  6454.                           overflow     := false;
  6455.                           n := 0 ;
  6456.                           loop
  6457.                             new_num := character'pos (ch)-character'pos ('0');
  6458.                             if n > a_repeat_factor'last / 10 then
  6459.                               overflow := true ;
  6460.                             else
  6461.                               n := n * 10 ;
  6462.                               if a_repeat_factor'last - new_num - 1 < n then
  6463.                                 -- the -1 is because we use 
  6464.                                 -- the 'last as infinity 
  6465.                                 overflow := true ;
  6466.                               else
  6467.                                 n := n + new_num ;
  6468.                                 set_repeat_prompt( true , n ) ;
  6469.                                 crt_windows.get_character( ch , TmpCmd ) ;
  6470.                               end if ;
  6471.                             end if ;
  6472.                           exit when ( TmpCmd /= digit_command ) or overflow;
  6473.                           end loop ;
  6474.                           if overflow then
  6475.                             error( " Repeat Factor Too Large " ,
  6476.                                not_fatal_error ,operator_wait ,short_beep ) ;
  6477.                             set_repeat_prompt( true , -1 ) ;
  6478.                             Tmp_New_Repeat := 1 ;
  6479.                             TmpCmd := illegal_command ;
  6480.                           else 
  6481.                             Tmp_New_Repeat := n ;
  6482.                           end if;
  6483.                           redo_once := true ;
  6484.                           if TmpCmd = infinity_command then
  6485.                             set_repeat_prompt( true , infinity );
  6486.                             Tmp_New_Repeat := infinity ;
  6487.                           end if ;
  6488.           when others           => null ; 
  6489.         end case ;
  6490.       end get_repeat_factor_and_command ;
  6491.        
  6492.     begin -- get_next_command
  6493.       redo_once := false ;
  6494.       if ( Old_Repeat /= 1 ) then 
  6495.         set_repeat_prompt( true , -1 ) ;
  6496.       end if ;
  6497.       Tmp_New_Repeat := 1 ;
  6498.       loop
  6499.         if need_prompt then
  6500.           if main_prompt_on then
  6501.             set_repeat_prompt ( true , -1 ) ;
  6502.             prompt(main_command_prompt);
  6503.           else 
  6504.             set_repeat_prompt ( true , -1 ) ;
  6505.             prompt(alternate_command_prompt);
  6506.           end if ;
  6507.           need_prompt:=false;
  6508.           show_cursor;
  6509.         end if ;
  6510.         get_repeat_factor_and_command ;
  6511.         if TmpCmd = show_other_prompt_command 
  6512.         and then allow_alternate_prompt_command then
  6513.           main_prompt_on:=not main_prompt_on;
  6514.           need_prompt:=true;
  6515.         end if ;
  6516.       exit when (TmpCmd /= show_other_prompt_command) 
  6517.             and (TmpCmd /= illegal_command)
  6518.             and (TmpCmd /= infinity_command) ;
  6519.       end loop ;
  6520.       need_prompt := (not main_prompt_on) or need_prompt ;  
  6521.         -- we need to prompt later if we left it off.... 
  6522.       new_command := TmpCmd ;
  6523.       if redo_once and Tmp_New_Repeat = 1 then
  6524.         -- they typed 1 in by themselves, and now we really should
  6525.         -- redisplay once
  6526.         set_repeat_prompt( true , -1 ) ;
  6527.       end if ;
  6528.       New_Repeat := Tmp_New_Repeat ;
  6529.     end get_next_command ;
  6530.      
  6531.   begin -- editor_misc
  6532.     -- EDITMISC by SAIC/Clearwater Misc Editor Routines        22 Jan 85
  6533.     null ;
  6534.   end editor_misc ;
  6535.   
  6536.   --$$$- EDITMISC
  6537.  
  6538. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6539. --debug
  6540. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6541.  
  6542.   --$$$+ DEBUG
  6543.    
  6544.   with text_io ;
  6545.   use  text_io ;
  6546.    
  6547.   --
  6548.   -- File 010
  6549.   --
  6550.   -- Editor Written By Robert S. Cymbalski
  6551.   --                   Science Applications International Corporation
  6552.   --                   Energy Systems Group
  6553.   --                   Ada Software Development Project Team
  6554.   --                   2280 U.S. Highway 19 North, Suite 120
  6555.   --                   Clearwater, Florida  33575
  6556.   --
  6557.   -- Debug Routines Written Januaray 1985, Robert S. Cymbalski
  6558.   --
  6559.   --
  6560.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  6561.   -- 
  6562.       
  6563.   with string_library  ;
  6564.   use  string_library  ;
  6565.    
  6566.   with basic_io_system ;
  6567.   use  basic_io_system ;
  6568.    
  6569.   with crt_windows     ;
  6570.   use  crt_windows     ;
  6571.    
  6572.   with Wordp_Globals   ;
  6573.   use  Wordp_Globals   ;
  6574.  
  6575.   with editor_globals         ;
  6576.   use  editor_globals         ;
  6577.    
  6578.   with edit_windows           ;
  6579.    
  6580.   with editor_misc ;
  6581.   use  editor_misc ;
  6582.   use  copy_package ;
  6583.    
  6584.   package debugger is
  6585.    
  6586.     procedure pause ;
  6587.      
  6588.     procedure show_buffer ( debug_opt : in character := ascii.nul ) ;
  6589.      
  6590.   end debugger ;
  6591.    
  6592.   package body debugger is
  6593.    
  6594.     procedure pause is
  6595.       c : character ;
  6596.       spec : an_editor_command ;
  6597.     begin -- pause
  6598.       basic_io_system.put("  Enter <space> to continue ");
  6599.       get_character( c , spec ) ;
  6600.     end pause ;
  6601.      
  6602.     procedure show_buffer ( debug_opt : in character := ascii.nul ) is
  6603.      
  6604.       users_opt : character ;
  6605.      
  6606.       procedure show_c ( val , len : integer ) is
  6607.       begin
  6608.         if val < 0 then
  6609.           -- impossible
  6610.           basic_io_system.put(" XXX");
  6611.         elsif val < 32 then
  6612.           -- control character
  6613.           -- basic_io_system.put("  ^");
  6614.           -- basic_io_system.put( character'val( val + 64 ) ) ;
  6615.           basic_io_system.put(val,len);
  6616.         elsif val < 127 then
  6617.           basic_io_system.put("  """);
  6618.           basic_io_system.put( character'val(val));
  6619.         elsif val <= 999 then
  6620.           basic_io_system.put(val,len);
  6621.         else
  6622.           basic_io_system.put(" XXX");
  6623.         end if ;
  6624.       end show_c ;
  6625.        
  6626.       procedure show_values ( b : in an_editor_buffer ) is
  6627.        
  6628.         procedure show_x ( c : in cursor_position ) is
  6629.         begin -- show_x
  6630.           basic_io_system.put( c.line_start , 5 ) ;
  6631.           basic_io_system.put(" [");
  6632.           basic_io_system.put( c.file_line_number , 5 ) ;
  6633.           basic_io_system.put(" /");
  6634.           basic_io_system.put( c.column_offset , 3 ) ;
  6635.           basic_io_system.put(" ] ");
  6636.           basic_io_system.put( c.buffer_position , 6 ) ;
  6637.           basic_io_system.put_line ;
  6638.         end show_x ;
  6639.          
  6640.         procedure ot ( s : string ; n : integer ) is
  6641.         begin
  6642.           text_io.put( s ) ; 
  6643.           basic_io_system.put( n , 5 ) ;
  6644.           basic_io_system.put_line ;
  6645.         end ;
  6646.          
  6647.       begin
  6648.         basic_io_system.put_line;
  6649.         basic_io_system.put(" Buffer Num "); 
  6650.         basic_io_system.put(b.buffer_number,2) ;
  6651.         basic_io_system.put_line;
  6652.         if b.still_reading_input_file then
  6653.           basic_io_system.put(" Reading Input File");
  6654.         else
  6655.           basic_io_system.put(" Done Reading Input File ");
  6656.         end if ;
  6657.         basic_io_system.put_line ;
  6658.         ot ( " Present Top Block " , b.prestopblock ) ;
  6659.         ot ( " Present Bot Block " , b.presbotblock ) ;
  6660.         -- ot ( " Present Cpy Block " , b.prescopyblock) ;
  6661.         -- ot ( " Present Cpy Leng  " , b.prescopylen  ) ;
  6662.         ot ( " Bufcount          " , b.bufcount     ) ;
  6663.         if b.open_buffer_area then
  6664.           ot ( " First Open Positn " , b.first_open_position);
  6665.           ot ( " Last Open Positin " , b.last_open_position);
  6666.         else
  6667.           ot ( " Buffer Closed     " , 0 ) ;
  6668.         end if ;
  6669.         basic_io_system.put(" Top Cursor "); show_x( b.top_screen_cursor ) ;
  6670.         basic_io_system.put(" Nxt Cursor "); show_x( b.next_screen_cursor) ;
  6671.         basic_io_system.put(" Fxd Cursor "); show_x( b.fixed_cursor      ) ;
  6672.         basic_io_system.put(" Mov Cursor "); show_x( b.moving_cursor     ) ;
  6673.         basic_io_system.put(" Flt Cursor "); show_x( b.floating_cursor   ) ;
  6674.         basic_io_system.put(" Buf Count  "); basic_io_system.put( b.bufcount,5) ; basic_io_system.put_line;
  6675.         basic_io_system.put_line;
  6676.       end ;
  6677.        
  6678.       procedure show_insides( e : t_buffer ; start : type_buffer_position ;
  6679.                               lowest , highest : type_buffer_position ) is
  6680.         do_length : integer := 320 ;
  6681.         p1 , p2 : type_buffer_position ;
  6682.         ln_start , ln_posn : type_buffer_position ;
  6683.       begin
  6684.         if start - do_length / 2 < lowest then
  6685.           p1 := lowest ;
  6686.         else
  6687.           p1 := start - do_length / 2 ;
  6688.         end if ;
  6689.         if p1 + do_length - 1 > highest then
  6690.           p2 := highest ;
  6691.           do_length := highest - lowest + 1 ;
  6692.         else
  6693.           p2 := p1 + do_length - 1 ;
  6694.         end if ;
  6695.         -- p1 is starting location
  6696.         -- p2 is stopping location
  6697.         -- do_length is number of positions to do
  6698.         basic_io_system.put("  Line Start At ");
  6699.         basic_io_system.put(start);
  6700.         basic_io_system.put_line;
  6701.         basic_io_system.put("  Lowest Is ");
  6702.         basic_io_system.put(lowest);
  6703.         basic_io_system.put("  Highest Is ");
  6704.         basic_io_system.put(highest);
  6705.         basic_io_system.put_line ;
  6706.         ln_start := p1 ;
  6707.         loop
  6708.           -- for each group of 16
  6709.           basic_io_system.put(ln_start,5);
  6710.           basic_io_system.put("  ");
  6711.           -- we are working with e.data() which is basic_io_system.extended_character
  6712.           ln_posn := ln_start ;
  6713.           loop
  6714.             show_c( e(ln_posn).data , 4 ) ;
  6715.             ln_posn := ln_posn + 1 ;
  6716.           exit when ( ln_posn = ln_start + 16 ) or ( ln_posn > p2 ) ;
  6717.           end loop ;
  6718.           basic_io_system.put_line;
  6719.           ln_start := ln_start + 16 ;
  6720.         exit when ln_start > p2 ;
  6721.         end loop ;
  6722.       end;
  6723.        
  6724.       procedure do_memory is
  6725.         type ip is access each_position ;
  6726.         i : ip ;
  6727.         n : integer ;
  6728.       begin
  6729.         n := 0 ;
  6730.         loop
  6731.           for j in 1 .. 100 loop i := new each_position ; end loop ;
  6732.           n := n + 1 ;
  6733.           basic_io_system.put(n,5);
  6734.         exit when n = integer'last ;
  6735.         end loop ;
  6736.       end;
  6737.        
  6738.       procedure do_memory_2 is
  6739.         type ip is access integer ;
  6740.         i : ip ;
  6741.         n : integer ;
  6742.       begin
  6743.         n := 0 ;
  6744.         loop
  6745.           for j in 1 .. 100 loop i := new integer ; end loop ;
  6746.           n := n + 1 ;
  6747.           basic_io_system.put(n,5);
  6748.         exit when n = integer'last ;
  6749.         end loop ;
  6750.       end;
  6751.        
  6752.       function starting_pos ( def : integer ) return integer is
  6753.       begin
  6754.         basic_io_system.put("  Enter Starting Position => ");
  6755.         return get_number( 0 , 0 , 0 , 32767 , 5 , def ) ;
  6756.       end ;
  6757.        
  6758.       function debug_option return character is
  6759.       begin -- debug_option
  6760.         return char_or_abort ( ' ' , ' ' , 'C' , 'P' , 'R' , 'V' , 'Q' ,
  6761.                                            'X' , 'B' ) ;
  6762.       end debug_option ;
  6763.      
  6764.     begin
  6765.       crt_windows.clear_window( crt_windows.current_window ) ;
  6766.       edit_windows.store_shift ;
  6767.       users_opt := debug_opt ;
  6768.       if users_opt = ascii.nul then
  6769.         users_opt := debug_option ;
  6770.       end if ;
  6771.       loop 
  6772.         case users_opt is
  6773.           when 'C' => do_memory_2 ;
  6774.           when 'P' => do_memory   ;
  6775.           when 'R' => edit_windows.refresh_screen ;
  6776.           when 'V' => show_values( current_buffer ) ;
  6777.           when 'X' | 'B' |
  6778.                'N' | 'M' => copy_debug ( users_opt ) ;
  6779.           when others => show_insides( current_buffer.e_buf , 
  6780.                                        starting_pos (
  6781.                                        current_buffer.fixed_cursor.line_start),
  6782.                                        0,
  6783.                                        current_buffer.bufcount);
  6784.         end case ;
  6785.         basic_io_system.put_line;
  6786.         basic_io_system.put("  Enter New Debug Option ? ");
  6787.         users_opt := debug_option ;
  6788.       exit when users_opt = 'Q' ;
  6789.       end loop ;
  6790.       edit_windows.restore_shift ;
  6791.     end show_buffer ;
  6792.      
  6793.   begin -- debugger
  6794.     -- DEBUG    by SAIC/Clearwater Debugger Routines           22 Jan 85
  6795.     null ;
  6796.   end debugger ;
  6797.    
  6798.   --$$$- DEBUG
  6799.  
  6800. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6801. --editfind
  6802. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6803.  
  6804.   --$$$+ EDITFIND
  6805.  
  6806.   --
  6807.   -- File 017
  6808.   --
  6809.   -- Editor Written By Robert S. Cymbalski
  6810.   --                   Science Applications International Corporation
  6811.   --                   Energy Systems Group
  6812.   --                   Ada Software Development Project Team
  6813.   --                   2280 U.S. Highway 19 North, Suite 120
  6814.   --                   Clearwater, Florida  33575
  6815.   --
  6816.   --
  6817.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  6818.   -- 
  6819.  
  6820.   with string_library  ;
  6821.   use  string_library  ;
  6822.  
  6823.   with basic_io_system ;
  6824.  
  6825.   with crt_customization ;
  6826.   use  crt_customization ;
  6827.   use  crt               ;
  6828.   use  editor_customization ;
  6829.  
  6830.   with crt_windows     ;
  6831.  
  6832.   with Wordp_Globals   ;
  6833.   use  Wordp_Globals   ;
  6834.  
  6835.   with editor_globals  ;
  6836.   use  editor_globals  ;
  6837.  
  6838.   with buffer_package  ;
  6839.   use  buffer_package  ;
  6840.   use  buffer_general  ;
  6841.   use  buffer_lines    ;
  6842.  
  6843.   with edit_windows    ;
  6844.   use  edit_windows    ;
  6845.  
  6846.   with markers         ;
  6847.   use  markers         ;
  6848.  
  6849.   with editor_misc     ;
  6850.   use  editor_misc     ;
  6851.  
  6852.   package editor_Find is
  6853.  
  6854.     procedure do_find_command ( go_forward : in boolean ;
  6855.                                 Repeat_Factor : a_repeat_factor ;
  6856.                                 returned_command : in out an_editor_command ) ;
  6857.  
  6858.     longest_search_target : constant integer := 255 ;
  6859.     subtype search_target_index is integer range 0 .. longest_search_target ;
  6860.     type a_target is array ( search_target_index range
  6861.                              1 .. longest_search_target) of extended_character ;
  6862.     Search_Target_Defined : boolean := false ;
  6863.     Search_Target         : a_target ;
  6864.     Search_Target_Length  : Type_Line_Length := 0 ;
  6865.     Replace_String_Defined: boolean := false ;
  6866.     Replace_String        : a_target ;
  6867.     Replace_String_Length : Type_Line_Length := 0 ;
  6868.     
  6869.   end ;
  6870.  
  6871.   package body editor_find is
  6872.  
  6873.     Token_Kind : array ( extended_character ) of extended_character ;
  6874.     Kind_Alpha_Numeric : constant Extended_Character := 
  6875.                                       extended_character( character'pos('A') ) ;
  6876.  
  6877.     procedure do_find_command ( go_forward : in boolean ;
  6878.                                 Repeat_Factor : a_repeat_factor ;
  6879.                                 returned_command : in out an_editor_command ) is
  6880.       
  6881.       find_exit  : exception ;
  6882.       reject_cmd : exception ;
  6883.       type type_Find_Mode  is (Literal_Mode,Token_Mode) ;
  6884.       Find_Mode  : type_Find_Mode ;
  6885.       Do_A_Case_Sensitive_Search : boolean ;
  6886.       Number_Found_So_Far        : a_repeat_factor     := 0 ;
  6887.       Verify_Each_Replacement    : boolean             := false ;
  6888.       Users_String_Delimiter     : extended_character ;
  6889.       Minimum_Displacement_Of_Character_From_End_Of_Search_String :   
  6890.                 array ( extended_character ) of integer ;
  6891.                 -- displacement of character from end
  6892.       Multiple_Character_Match_Displacement_Amount : 
  6893.                 array( search_target_index range
  6894.                        0 .. longest_search_target ) of integer ;
  6895.                 -- displacement for double letters
  6896.       The_Search_Target         : a_target ;
  6897.       The_Replacement_String    : a_target ;
  6898.       Search_String_Length      : search_target_index ;
  6899.       Replacement_String_Length : search_target_index ;
  6900.       Last_Find_Location        : text_position := no_set_location ;
  6901.       Old_Find_Location         : text_position := no_set_location ;
  6902.       User_Find_Character       : Character ;
  6903.       User_Find_Extended_Character : Extended_Character ;
  6904.       User_Find_Editor_Command  : an_editor_command ;
  6905.       Screen_Is_Not_Erased      : boolean := true ;
  6906.       Use_Last_Entered_String   : boolean := false ;
  6907.        
  6908.       Fixed_Cursor_Line_Start       : type_buffer_position ;
  6909.       Fixed_Cursor_Buffer_Position  : type_buffer_position ;
  6910.       First_Line_Character_Position : type_buffer_position ;
  6911.       Last_Line_Character_Position  : type_buffer_position ;
  6912.       Lines_Leading_Spaces          : type_leading_spaces  ;
  6913.       Lines_Last_Column             : column_position      ;
  6914.       Lines_Text_Length             : type_line_length     ;
  6915.        
  6916.       target_found : boolean ;
  6917.       current_leading : type_leading_spaces ;
  6918.        
  6919.       procedure get_c_or_cmd( c  : out character                        ;
  6920.                               cmd: out editor_globals.an_editor_command ) is
  6921.         -- get either a printable character or else get an editor command...
  6922.         -- note that here, printable characters take priority over commands
  6923.         physical_c : character ;
  6924.         physical_command : crt.special_keys ;
  6925.       begin -- get_c_or_cmd
  6926.         crt_windows.key_input( physical_c , physical_command ) ;
  6927.         if physical_command = key_character 
  6928.         and then physical_c in ' ' .. '~' then
  6929.           -- easy... is just a printable character ...????
  6930.           c := physical_c ;
  6931.           cmd := editor_customization.illegal_command ;
  6932.           -- I really wanted to use editor_globals.illegal_command.......
  6933.         else
  6934.           -- need to find out what it might be...
  6935.           translate( physical_c , physical_command , c , cmd ) ;
  6936.         end if ;
  6937.       end get_c_or_cmd ;
  6938.          
  6939.       function e_character( c : character ) return extended_character is
  6940.       begin -- e_character
  6941.         return extended_character( character'pos( c ) ) ;
  6942.       end e_character ;
  6943.        
  6944.       Procedure Get_Next_Character_Of_Find_Command is
  6945.       begin
  6946.         get_c_or_cmd( User_Find_Character , User_Find_Editor_Command ) ;
  6947.         User_Find_Extended_Character := e_character ( User_Find_Character ) ;
  6948.         If User_Find_Editor_Command = left_command then
  6949.           null ; -- put(ascii.bs);
  6950.         elsif User_Find_Editor_Command = backward_character_command then
  6951.           null ; -- put(ascii.bs);
  6952.         elsif User_Find_Character /= ascii.nul then
  6953.           put(User_Find_Character) ;
  6954.         elsIf User_Find_Editor_Command = advance_line_command then 
  6955.           User_Find_Editor_Command := Illegal_Command ;
  6956.           -- NOTE: For now, we do not allow <cr> to be in a find target
  6957.           -- or a replacement string......
  6958.           -- To reinstate, simply un_comment out these lines and comment out
  6959.           -- the line turning the command illegal.  Then, you'll need to 
  6960.           -- correctly search past <eol> , and also correctly add 
  6961.           -- multiple lines in the replace routines
  6962.           -- If Screen_Is_Not_Erased then
  6963.             -- Screen_Is_Not_Erased := false ;
  6964.             -- clear_window( master_buffer ) ;
  6965.             -- goto_line_column( master_buffer , 1 , 1 ) ;
  6966.           -- else
  6967.             -- put(ascii.cr);
  6968.           -- end if ;
  6969.         end if ;
  6970.       end Get_Next_Character_Of_Find_Command ;
  6971.        
  6972.       Procedure Skip_Blanks is
  6973.       begin
  6974.         while (User_Find_Character = ' ') 
  6975.         or else ( (User_Find_Character = ascii.nul )
  6976.             and ( User_Find_Editor_Command /= reject_command ) ) loop
  6977.           Get_Next_Character_Of_Find_Command ;
  6978.         end loop ;
  6979.       end Skip_Blanks ;
  6980.        
  6981.       function map_up ( c : character ) return character is
  6982.       begin -- map_up 
  6983.         if c in 'a' .. 'z' then
  6984.           return character'val( character'pos(c) 
  6985.                               - character'pos('a')
  6986.                               + character'pos('A') ) ;
  6987.         else
  6988.           return c ;
  6989.         end if ;
  6990.       end map_up ;
  6991.        
  6992.       function map_up ( c : extended_character ) return extended_character is
  6993.         -- extended character set is the ascii representation...
  6994.       begin -- map_up 
  6995.         if c in extended_character(97) .. extended_character(97 + 25) then
  6996.           return extended_character( c - 32 ) ;
  6997.         else
  6998.           return c ;
  6999.         end if ;
  7000.       end map_up ;
  7001.        
  7002.       Procedure Process_Command_Line_Options is
  7003.       begin
  7004.         User_Find_Character := map_up(User_Find_Character) ;
  7005.         while (User_Find_Character = 'L') 
  7006.            or (User_Find_Character = 'T') 
  7007.            or (User_Find_Character = 'V') 
  7008.            or (User_Find_Character = 'C') 
  7009.            or (User_Find_Character = 'I') loop
  7010.           case User_Find_Character is
  7011.             when 'L' => Find_Mode := Literal_Mode ;
  7012.             when 'T' => Find_Mode := Token_Mode   ;
  7013.             when 'V' => Verify_Each_Replacement := true  ;
  7014.             when 'C' => Do_A_Case_Sensitive_Search := true ;
  7015.             when 'I' => Do_A_Case_Sensitive_Search := false ;
  7016.             when others => null ;
  7017.           end case ;
  7018.           Get_Next_Character_Of_Find_Command ;
  7019.           User_Find_Character := map_up(User_Find_Character) ;
  7020.         end loop ;
  7021.         Skip_Blanks ;
  7022.         if (User_Find_Character='S') or (User_Find_Character='s') then
  7023.           Use_Last_Entered_String := true ;
  7024.         end if ;
  7025.       end Process_Command_Line_Options ;
  7026.        
  7027.       function Tok_Kind ( c : character ) return extended_character is
  7028.       begin -- tok_kind
  7029.         return token_kind( extended_character( character'pos( c ) ) ) ;
  7030.       end tok_kind ;
  7031.      
  7032.       Procedure Parse_string ( pattern : in out a_target ; 
  7033.                                plength : in out integer) is
  7034.         Total_Pattern_Length : integer := 0 ;
  7035.       begin
  7036.         Skip_Blanks ;  -- to get the first delimiter 
  7037.         if token_kind( user_find_extended_character ) = tok_kind('A') 
  7038.         or else User_Find_Character = ascii.nul then
  7039.           -- error, we don't allow alpha-numerics
  7040.           error("Invalid Delimiter.", not_fatal_error ,
  7041.                 operator_wait , extra_short_beep   ) ;
  7042.           User_Find_Character := ascii.nul ;
  7043.           User_Find_Extended_Character := e_character( ascii.nul ) ;
  7044.           User_Find_Editor_Command     := reject_command ;
  7045.         end if ;
  7046.         if User_Find_Character = ascii.nul then
  7047.           -- do nothing ...
  7048.           plength := 0 ;
  7049.         else
  7050.           Users_String_Delimiter := User_Find_Extended_Character ;
  7051.           Total_Pattern_Length := 0 ;
  7052.           loop
  7053.             Get_Next_Character_Of_Find_Command ;
  7054.             if User_Find_Editor_Command = left_command 
  7055.             or else User_Find_Editor_Command = backward_character_command then
  7056.               if (pattern(Total_Pattern_Length) /= e_character(ascii.cr) ) 
  7057.               and (Total_Pattern_Length>0) then
  7058.                 put(ascii.bs) ;
  7059.                 put(' ') ;
  7060.                 put(ascii.bs) ;
  7061.                 Total_Pattern_Length := Total_Pattern_Length - 1 ;
  7062.               end if ;
  7063.             else
  7064.               Total_Pattern_Length := Total_Pattern_Length + 1 ;
  7065.               if User_Find_Editor_Command = advance_line_command then
  7066.                 pattern( total_pattern_length ) := e_character(ascii.cr) ;
  7067.               else
  7068.                 pattern(Total_Pattern_Length) := User_Find_Extended_Character ;
  7069.               end if ;
  7070.             end if ;
  7071.           exit when ( User_Find_Extended_Character = Users_String_Delimiter ) 
  7072.                  or ( Total_Pattern_Length = Max_Line_Length ) 
  7073.                  or ( User_Find_Editor_Command = reject_command ) ;
  7074.           end loop ;
  7075.           if Total_Pattern_Length = Max_Line_Length then
  7076.             error("Your pattern is too long      " , not_fatal_error ,
  7077.                   operator_wait , extra_short_beep                ) ;
  7078.             User_Find_Character := ascii.nul ;
  7079.             User_Find_Extended_Character := e_character( ascii.nul ) ;
  7080.             User_Find_Editor_Command     := reject_command ;
  7081.           end if ;
  7082.           plength := Total_Pattern_Length - 1 ; -- do'nt include final Delimiter
  7083.         end if ;
  7084.       end parse_string ;
  7085.          
  7086.       Procedure Set_Table is
  7087.         pla : integer ;
  7088.         -- we set up the table to tell us how far to move before checking
  7089.         -- the next character.  We do the string in the reverse order that
  7090.         -- we will eventually look at it in.  This makes sure that we move
  7091.         -- the minumin number of characters needed to match again.
  7092.          
  7093.         Procedure Put_Table ( c : extended_character ; i : integer ) is
  7094.           -- put the number into the table for the character c.  if case
  7095.           -- is not checked, also put it in for the other case.
  7096.         begin
  7097.           Minimum_Displacement_Of_Character_From_End_Of_Search_String(c):=i;
  7098.           if not Do_A_Case_Sensitive_Search then
  7099.             if c in extended_character(65) .. extended_character( 65 + 25 ) then
  7100.               Minimum_Displacement_Of_Character_From_End_Of_Search_String
  7101.                           ( c + 32 ) := i ;
  7102.             end if ;
  7103.           end if ;
  7104.         end put_table ;
  7105.          
  7106.       begin -- set_table
  7107.         -- now, this is for case sensitivity
  7108.         -- if might slow the process down horribly
  7109.         if not Do_A_Case_Sensitive_Search then
  7110.           for pla in 1 .. Search_String_Length loop
  7111.             The_Search_Target(pla) := map_up( The_Search_Target(pla) ) ;
  7112.           end loop ;
  7113.         end if ;
  7114.         if go_forward then
  7115.           for pla in extended_character loop 
  7116.             Minimum_Displacement_Of_Character_From_End_Of_Search_String(pla) 
  7117.               := Search_String_Length ;
  7118.           end loop ;
  7119.           For pla in 1 .. search_string_length - 1 loop
  7120.             put_table( The_Search_Target( pla ) , Search_String_Length - Pla ) ;
  7121.           end loop ;
  7122.           -- that takes care of the individual character
  7123.           put_table(The_Search_Target(search_string_length) , Max_Line_Length
  7124.                                                             + Max_Line_Length );
  7125.           -- set specialty routine for last character
  7126.         else
  7127.           for pla in extended_character loop 
  7128.             Minimum_Displacement_Of_Character_From_End_Of_Search_String(pla) 
  7129.               := (-Search_String_Length) ;
  7130.           end loop ;
  7131.           -- now we have set all characters to Skip_Blanks the maximum 
  7132.           -- amount possible
  7133.           for pla in reverse 2 .. Search_String_Length loop
  7134.             put_table(The_Search_Target(pla), 1-pla) ;
  7135.           end loop ;
  7136.           put_table( The_Search_Target(1) , Max_Line_Length+Max_Line_Length);
  7137.           -- special for last character
  7138.         end if ;
  7139.       end set_table ;
  7140.        
  7141.       Procedure Compare_Two is
  7142.       begin
  7143.         for match_char in 0 .. Max_Line_Length loop
  7144.           if go_forward then
  7145.             Multiple_Character_Match_Displacement_Amount(match_char) := 1 ;
  7146.           else
  7147.             Multiple_Character_Match_Displacement_Amount(match_char) := -1 ;
  7148.           end if ;
  7149.         end loop ;
  7150.       end compare_two ;
  7151.              
  7152.       Procedure put_prompt ( left , right  : string ;
  7153.                              repeat_factor : integer ;
  7154.                              show_literal_token_prompt : boolean := true ) is
  7155.       begin 
  7156.         clear_prompt(master_buffer) ;
  7157.         goto_prompt_line_column( master_buffer , 1 , 1 ) ;
  7158.         if go_forward then
  7159.            put('>') ;
  7160.         else
  7161.            put('<') ;
  7162.         end if ;
  7163.         put(left) ;
  7164.         put('[')  ;
  7165.         if repeat_factor = infinity then
  7166.           if returned_command = find_command then
  7167.             put("Last");
  7168.           else
  7169.             put("Every") ;
  7170.           end if ;
  7171.         elsif repeat_factor = 1 then
  7172.           put("Next") ;
  7173.         else
  7174.           put(repeat_factor,1) ;
  7175.         end if ;
  7176.         put("]:") ;
  7177.         if show_literal_token_prompt then
  7178.           if Find_Mode=Token_Mode then
  7179.             put(" L(it") ;
  7180.           else 
  7181.             put(" T(ok") ;
  7182.           end if ;
  7183.           if Do_A_Case_Sensitive_Search then
  7184.             put(" I(nsens") ;
  7185.           else
  7186.             put(" C(ase") ;
  7187.           end if ;
  7188.         end if ;
  7189.         put(right) ;
  7190.       end put_prompt ;
  7191.        
  7192.     Procedure Return_Quit_Stop( dd : character ) is
  7193.       -- do the desired...
  7194.       -- we could also be here on a disk full condition, '!' is the code
  7195.       current_leading : type_leading_spaces ;
  7196.     begin
  7197.       current_leading := num_leading_spaces( master_buffer ,
  7198.               master_buffer.fixed_cursor.line_start ) ;
  7199.       if master_buffer.fixed_cursor.column_offset 
  7200.         <= current_leading then
  7201.         master_buffer.fixed_cursor.column_offset 
  7202.           := current_leading + 1 ;
  7203.       end if ;
  7204.       if dd = '!' then
  7205.         error("Disk Out Of Space During Find " , not_fatal_error ,
  7206.                operator_wait ,short_beep                          ) ;
  7207.       elsif dd = 'C' then
  7208.         jump_to_position ( master_buffer ,
  7209.                            last_find_location.line ,
  7210.                            last_find_location.column ,
  7211.                            false ) ;
  7212.       end if ;
  7213.       current_leading := num_leading_spaces( master_buffer ,
  7214.                                  master_buffer.fixed_cursor.line_start ) ;
  7215.       if master_buffer.fixed_cursor.column_offset <= current_leading then
  7216.         master_buffer.fixed_cursor.column_offset := current_leading + 1 ;
  7217.       end if ;
  7218.       if ( dd = 'Q' ) or ( dd = '!' ) then
  7219.         Returned_Command := quit_command ;
  7220.       else
  7221.         If not screen_is_not_erased then
  7222.           show_screen( master_buffer ) ;
  7223.         end if ;
  7224.       end if ;
  7225.       show_cursor( master_buffer ) ;
  7226.       raise find_exit ;
  7227.     end return_quit_stop ;
  7228.        
  7229.     Procedure chk_abort is
  7230.       -- this procedure will check to see if an abort has been pressed,
  7231.       -- <reject>, and if so will abort the find process and will restore
  7232.       -- the screen as is ...
  7233.       dd : character ;
  7234.     begin
  7235.       if basic_io_system.key_is_pressed then
  7236.         -- they want our attention...
  7237.         clear_prompt( master_buffer ) ;
  7238.         goto_prompt_line_column( master_buffer , 1 , 1 ) ;
  7239.         put(" Interrupted by user request...");
  7240.         get_next_character_of_find_command ;
  7241.         if User_Find_Editor_Command = reject_command then
  7242.           dd := 'C' ;
  7243.         else
  7244.           dd := map_up( User_Find_Character ) ;
  7245.         end if ;
  7246.         if (dd = 'Q') or (dd = 'C') or (dd = 'S') then
  7247.           return_quit_stop(dd) ;
  7248.         else
  7249.           put(ascii.bel);
  7250.         end if ;
  7251.       end if ;
  7252.     end chk_abort ;
  7253.  
  7254.     Procedure Fix_Fixed_Cursor is
  7255.       -- note the boundries of the current line for searching
  7256.     begin -- fix_fixed_cursor
  7257.       Fixed_Cursor_Line_Start       := master_buffer.fixed_cursor.line_start ;
  7258.       Lines_Leading_Spaces          := num_leading_spaces ( master_buffer ,
  7259.                                          fixed_cursor_line_start ) ;
  7260.       Lines_Text_Length             := line_length( master_buffer , 
  7261.                                          fixed_cursor_line_start ) ;
  7262.       First_Line_Character_Position := Fixed_Cursor_Line_Start + 2 ;
  7263.       Last_Line_Character_Position  := First_Line_Character_Position
  7264.                                          + Lines_Text_Length - 1 ;
  7265.       Lines_Last_Column             := Lines_Leading_Spaces 
  7266.                                          + Lines_Text_Length ;
  7267.       If master_buffer.fixed_cursor.column_offset > lines_last_column then
  7268.         if go_forward then
  7269.           Fixed_Cursor_Buffer_Position := Last_Line_Character_Position + 1 ;
  7270.         else
  7271.           -- do this on going backward -- else next line
  7272.           Fixed_Cursor_Buffer_Position := Last_Line_Character_Position ;
  7273.           -- assumes that we start searching at the current character 
  7274.         end if ;
  7275.       elsif master_buffer.fixed_cursor.column_offset < 
  7276.                       Lines_Leading_Spaces then
  7277.         if go_forward then
  7278.           Fixed_Cursor_Buffer_Position := First_Line_Character_Position ;
  7279.         else
  7280.           -- do this only on going forward ..... else prior line
  7281.           Fixed_Cursor_Buffer_Position := First_Line_Character_Position - 1 ;
  7282.         end if ;
  7283.       else
  7284.         -- need to set in the middle of the line 
  7285.         Fixed_Cursor_Buffer_Position := First_line_character_position
  7286.                                           + master_buffer.fixed_cursor
  7287.                                               .column_offset 
  7288.                                           - Lines_Leading_Spaces - 1 ;
  7289.       end if ;
  7290.     end fix_fixed_Cursor ;
  7291.      
  7292.     Procedure Un_Fix_Fixed_Cursor is 
  7293.     begin -- un_fix_fixed_cursor 
  7294.       master_buffer.fixed_cursor.buffer_position 
  7295.               := fixed_cursor_buffer_position ;
  7296.       master_buffer.fixed_cursor.column_offset 
  7297.               := Lines_Leading_Spaces + fixed_cursor_buffer_position 
  7298.                                       - first_line_character_position + 1 ;
  7299.     end un_fix_fixed_cursor ;
  7300.        
  7301.     Procedure find_The_Search_Target ( final_successfull : out boolean ) is
  7302.       
  7303.       successfull : boolean ;
  7304.        
  7305.       two_max : constant integer := Max_Line_Length + Max_Line_Length ;
  7306.        
  7307.       Function search_forward return boolean is
  7308.         Search_String_Place : search_target_index ;
  7309.         Buffer_Place        : integer          ;
  7310.                         -- because we can set values to it temporarily which
  7311.                         -- would not be valid for type_buffer_position  ;
  7312.         New_Displacement    : integer          ;
  7313.         New_Multiple_Character_Displacement : integer ;
  7314.         Save_Buffer_Place   : type_buffer_position  ;
  7315.         Is_Good             : boolean          ;
  7316.       begin
  7317.         Fix_Fixed_Cursor ;
  7318.         -- first, tell the cursor to begin looking for the end of the
  7319.         -- string starting here...
  7320.         Buffer_Place := Fixed_Cursor_Buffer_Position 
  7321.                         + Search_String_Length - 1 ; 
  7322.           -- the last char of the word could be here at the cursor
  7323.           -- position offset by the word length minus one
  7324.         loop 
  7325.           -- here we are looping until we really find it
  7326.           loop
  7327.             --here we are looping until we either find or fail to find
  7328.             -- the first(last) character of the string.  
  7329.             If Buffer_Place > Last_Line_Character_Position then
  7330.               -- past end of line, move to new line ...
  7331.               Master_Buffer.Fixed_Cursor.Column_Offset := 0 ; -- use leading sp
  7332.               If cursor_forward_line then
  7333.                 -- we are ready to work this new line
  7334.                 chk_abort ;
  7335.                 Fix_Fixed_Cursor ;
  7336.                 Buffer_Place := First_Line_Character_Position
  7337.                                 + Search_String_Length - 1 ; 
  7338.               else
  7339.                 -- unable to move, at end of buffer 
  7340.                 return false ; -- hit end of buffer w/o finding anything 
  7341.               end if ;
  7342.             else
  7343.               -- here if still on the same line...... ready to check....
  7344.               New_Displacement 
  7345.                 := Minimum_Displacement_Of_Character_From_End_Of_Search_String(
  7346.                   master_buffer.e_buf(type_buffer_position(Buffer_Place)).data);
  7347.           exit when ( New_Displacement = Two_Max ) ;
  7348.             -- signal for end of word is found here....
  7349.               Buffer_Place := Buffer_Place + New_Displacement ;
  7350.             end if ;
  7351.           end loop ;
  7352.           -- we end up here only when we find a valid last character .....
  7353.           Save_Buffer_Place := Buffer_Place ;
  7354.           Buffer_Place      := Buffer_Place - 1 ; -- move one char back from end
  7355.             -- set to look at next character down
  7356.           Search_String_Place := Search_String_Length - 1 ; 
  7357.             -- last already checked
  7358.           Is_Good := True ;
  7359.           Loop
  7360.           Exit When Search_String_Place = 0 ; -- SUCCESS !!!!
  7361.             if Do_A_Case_Sensitive_Search then
  7362.               Is_Good := The_Search_Target(Search_String_Place) 
  7363.                            = master_buffer.e_buf(type_buffer_position(
  7364.                                                            Buffer_Place)).data ;
  7365.             else
  7366.               Is_Good := The_Search_Target(Search_String_Place) 
  7367.                            = map_up(master_buffer.e_buf(
  7368.                                type_buffer_position(Buffer_Place)).data) ;
  7369.             end if ;
  7370.           Exit When Not Is_Good ;
  7371.             Search_String_Place := Search_String_Place - 1 ;
  7372.             Buffer_Place := Buffer_Place - 1 ;
  7373.           end loop ;
  7374.           if Is_Good then
  7375.             -- We Found The String ....... Return First Character Position
  7376.             Fixed_Cursor_Buffer_Position := Buffer_Place + 1 ;
  7377.               -- because the above loop went past one ...
  7378.             return True ;
  7379.           else
  7380.             -- found a mismatch
  7381.             -- last good character is at Search_String_Place + 1
  7382.             New_Multiple_Character_Displacement 
  7383.               := Minimum_Displacement_Of_Character_From_End_Of_Search_String(
  7384.                   master_buffer.e_buf(type_buffer_position(Buffer_Place)).data);
  7385.             if New_Multiple_Character_Displacement = two_max then
  7386.               Buffer_Place := Save_Buffer_Place + 1 ;
  7387.               -- we can always move one position.....
  7388.               -- ( failed to move more because that character was a success
  7389.               -- character for the end of the string 
  7390.             else
  7391.               Buffer_Place:=Buffer_Place + New_Multiple_Character_Displacement ;
  7392.             end if ;
  7393.             -- This is pretty obvious, at the place where we first did not
  7394.             -- have a match, we will attempt to move over the appropriate
  7395.             -- number of characters to continue on our way, unless it is
  7396.             -- the end of search target character, in which case we will
  7397.             -- only move the end_Buffer_Place over one position
  7398.             Save_Buffer_Place := Save_Buffer_Place 
  7399.                                  + Multiple_Character_Match_Displacement_Amount(
  7400.                                      Search_String_Place ) ;
  7401.             -- ok,  This says to move over the appropriate number of 
  7402.             -- characters to match the same String in the Target 
  7403.             --    it is measured from the end of the string to the new
  7404.             --    place we should start checking from
  7405.             If Save_Buffer_Place > Buffer_Place then
  7406.               Buffer_Place := Save_Buffer_Place ;
  7407.             end if ; -- move the furthest of the two choices...
  7408.             -- This is the finale ... in that we will move over as much
  7409.             -- as possible, based upon knowledge gained from the last 
  7410.             -- good character or the first bad character 
  7411.           end if ;
  7412.         end loop ;
  7413.       end search_forward ;
  7414.          
  7415.       Function search_backward return boolean is
  7416.         Search_String_Place : search_target_index ;
  7417.         Buffer_Place        : integer          ;
  7418.                         -- because we can set values to it temporarily which
  7419.                         -- would not be valid for type_buffer_position  ;
  7420.         New_Displacement    : integer          ;
  7421.         New_Multiple_Character_Displacement : integer ;
  7422.         Save_Buffer_Place   : type_buffer_position  ;
  7423.         Is_Good             : boolean          ;
  7424.       begin
  7425.         Fix_Fixed_Cursor ;
  7426.         -- first, tell the cursor to begin looking for the end of the
  7427.         -- string starting here...
  7428.         Buffer_Place := Fixed_Cursor_Buffer_Position ; -- first char to check
  7429.           -- the last char of the word could be here at the cursor
  7430.           -- position offset by the word length minus one
  7431.         loop 
  7432.           -- here we are looping until we really find it
  7433.           loop
  7434.             --here we are looping until we either find or fail to find
  7435.             -- the first(last) character of the string.  
  7436.             If Buffer_Place < first_line_character_position then
  7437.               -- past end of line, move to new line ...
  7438.               Master_Buffer.Fixed_Cursor.Column_Offset := 0 ; -- use leading sp
  7439.               If cursor_backward_line then
  7440.                 -- we are ready to work this new line
  7441.                 chk_abort ;
  7442.                 Fix_Fixed_Cursor ;
  7443.                 Buffer_Place := last_line_character_position
  7444.                                 - Search_String_Length + 1 ;
  7445.               else
  7446.                 -- unable to move, at start of buffer
  7447.                 return false ; -- hit start of buffer w/o finding anything
  7448.               end if ;
  7449.             else
  7450.               -- here if still on the same line...... ready to check....
  7451.               New_Displacement 
  7452.                 := Minimum_Displacement_Of_Character_From_End_Of_Search_String(
  7453.                   master_buffer.e_buf(type_buffer_position(Buffer_Place)).data);
  7454.           exit when ( New_Displacement = Two_Max ) ;
  7455.             -- signal for end of word is found here....
  7456.               Buffer_Place := Buffer_Place + New_Displacement ;
  7457.             end if ;
  7458.           end loop ;
  7459.           -- we end up here only when we find a valid last character .....
  7460.           Save_Buffer_Place := Buffer_Place ;
  7461.           Buffer_Place      := Buffer_Place + 1 ; -- move one char in from start
  7462.             -- set to look at next character down
  7463.           Search_String_Place := 2 ; -- first already checked
  7464.           Is_Good := True ;
  7465.           Loop
  7466.           Exit When Search_String_Place > Search_String_Length ; -- SUCCESS !!!!
  7467.             if Do_A_Case_Sensitive_Search then
  7468.               Is_Good := The_Search_Target(Search_String_Place) 
  7469.                            = master_buffer.e_buf(type_buffer_position(
  7470.                                                            Buffer_Place)).data ;
  7471.             else
  7472.               Is_Good := The_Search_Target(Search_String_Place) 
  7473.                            = map_up(master_buffer.e_buf(
  7474.                                type_buffer_position(Buffer_Place)).data) ;
  7475.             end if ;
  7476.           Exit When Not Is_Good ;
  7477.             Search_String_Place := Search_String_Place + 1 ;
  7478.             Buffer_Place := Buffer_Place + 1 ;
  7479.           end loop ;
  7480.           if Is_Good then
  7481.             -- We Found The String ....... Return First Character Position
  7482.             Fixed_Cursor_Buffer_Position := Save_Buffer_Place ;
  7483.             return True ;
  7484.           else
  7485.             -- found a mismatch
  7486.             -- last good character is at Search_String_Place - 1
  7487.             New_Multiple_Character_Displacement 
  7488.               := Minimum_Displacement_Of_Character_From_End_Of_Search_String(
  7489.                   master_buffer.e_buf(type_buffer_position(Buffer_Place)).data);
  7490.             if New_Multiple_Character_Displacement = two_max then
  7491.               Buffer_Place := Save_Buffer_Place - 1 ;
  7492.               -- we can always move one position.....
  7493.               -- ( failed to move more because that character was a success
  7494.               -- character for the end of the string 
  7495.             else
  7496.               Buffer_Place:=Buffer_Place + New_Multiple_Character_Displacement ;
  7497.             end if ;
  7498.             -- This is pretty obvious, at the place where we first did not
  7499.             -- have a match, we will attempt to move over the appropriate
  7500.             -- number of characters to continue on our way, unless it is
  7501.             -- the end of search target character, in which case we will
  7502.             -- only move the end_Buffer_Place over one position
  7503.             Save_Buffer_Place := Save_Buffer_Place 
  7504.                                  + Multiple_Character_Match_Displacement_Amount(
  7505.                                      Search_String_Place ) ;
  7506.             -- ok,  This says to move over the appropriate number of 
  7507.             -- characters to match the same String in the Target 
  7508.             --    it is measured from the end of the string to the new
  7509.             --    place we should start checking from
  7510.             If Save_Buffer_Place < Buffer_Place then
  7511.               Buffer_Place := Save_Buffer_Place ;
  7512.             end if ; -- move the furthest of the two choices...
  7513.             -- This is the finale ... in that we will move over as much
  7514.             -- as possible, based upon knowledge gained from the last 
  7515.             -- good character or the first bad character 
  7516.           end if ;
  7517.         end loop ;
  7518.       end search_backward ;
  7519.          
  7520.     begin -- find_The_Search_Target
  7521.       successfull := false ; -- haven't found the The_Search_Target yet
  7522.       loop
  7523.         -- look for the The_Search_Target : we know that cursor is set as the
  7524.         -- first character possible for the match string (on the left)
  7525.         if go_forward then
  7526.           successfull := search_forward ;
  7527.         else
  7528.           successfull := search_backward ;
  7529.         end if ;
  7530.         un_fix_fixed_Cursor ;
  7531.       exit when not successfull ; -- can't find...go away...
  7532.         -- In Token_Mode Find_Mode make sure the first and last characters 
  7533.         -- of the targer are on 'Token_Mode boundaries'
  7534.       exit when Find_Mode /= Token_Mode ;
  7535.         -- if not token mode, we are done and have been successfull.....
  7536.       exit when Token_Kind(The_Search_Target(1)) /= Kind_Alpha_Numeric ;
  7537.         -- if not alphanumeric, we don't do a token check anyway.....
  7538.         -- in that case, we are automatically successfull....
  7539.         if Fixed_Cursor_Buffer_Position 
  7540.          > First_Line_Character_Position then 
  7541.           successfull := Token_Kind(master_buffer.e_buf
  7542.                       (Fixed_Cursor_Buffer_Position).data)
  7543.                 /= Token_Kind(master_buffer.e_buf
  7544.                       (Fixed_Cursor_Buffer_Position-1).data) ;
  7545.           -- we do not have a successfull find if we are asking for a
  7546.           -- token and the first character is the same kind as the 
  7547.           -- previous character ...
  7548.         -- else on a line start boundry//ok.....
  7549.         end if ;
  7550.         if successfull 
  7551.         and then Fixed_Cursor_Buffer_Position 
  7552.                < Last_Line_Character_Position then 
  7553.           successfull := Token_Kind(master_buffer.e_buf
  7554.                       ( Fixed_Cursor_Buffer_Position
  7555.                         + Search_String_Length - 1 ).data)
  7556.                 /= Token_Kind(master_buffer.e_buf
  7557.                       ( Fixed_Cursor_Buffer_Position
  7558.                         + Search_String_Length ).data) ;
  7559.           -- we do not have a successfull find if we are asking for a
  7560.           -- token and the last character is the same kind as the
  7561.           -- following character ...
  7562.         -- else on a line end boundry//ok...or else failed previously
  7563.         -- and then we need to go around again...
  7564.         end if ;
  7565.         -- the following assumes that on a Token_Mode mismatch we will 
  7566.         -- throw all info away and start one after/before the place
  7567.         -- we are at
  7568.       exit when successfull ; -- because we are done......
  7569.         -- we end up here if we found it but failed on the token check
  7570.         if go_forward then
  7571.           Master_Buffer.Fixed_Cursor.Column_Offset 
  7572.             := Master_Buffer.Fixed_Cursor.Column_Offset + 1 ;
  7573.             -- because search looks for the last character at 
  7574.             -- cursor+Search_String_Length-1, which will start 1 character after
  7575.             -- the current match
  7576.         else
  7577.           Master_Buffer.Fixed_Cursor.Column_Offset 
  7578.             := Master_Buffer.Fixed_Cursor.Column_Offset - 1 ;
  7579.             -- again, we will make it the last character and we will
  7580.             -- then Skip_Blanks to one before it...
  7581.         end if ;
  7582.       end loop ;
  7583.       final_successfull := successfull ;
  7584.     end find_The_Search_Target ;
  7585.      
  7586.     Procedure Not_Enough_Found is
  7587.       dd : character ;
  7588.     begin
  7589.       clear_prompt( master_buffer ) ;
  7590.       goto_prompt_line_column( master_buffer , 1 , 1 ) ;
  7591.       if go_forward then
  7592.         put('>') ;
  7593.       else 
  7594.         put('<') ;
  7595.       end if ;
  7596.       put(" Error: ") ;
  7597.       if Number_Found_So_Far = 0 then
  7598.         put("String Not Found.") ;
  7599.       else
  7600.         put("Found only ") ;
  7601.         put(Number_Found_So_Far,0) ;
  7602.         put(" of the ") ;
  7603.         put(repeat_factor,0) ; 
  7604.         put(" required.") ;
  7605.       end if ;
  7606.       put("  Options: C(ontinue, Q(uit, S(top ") ;
  7607.       dd := crt_windows.char_or_abort( ' ' , ' ' , 'C' , 'Q' , 'S' ) ;
  7608.       if  not ( (dd = 'Q') or (dd = 'S') ) then
  7609.         dd := 'C' ;
  7610.       end if ;
  7611.       return_quit_stop( dd ) ;
  7612.     end not_enough_found ;
  7613.    
  7614.       Procedure replace_it is
  7615.         added_length : integer ;
  7616.         exit_replace_it : exception ;
  7617.         inserted_range : text_range ;
  7618.         successfull    : boolean    ;
  7619.         new_number     : a_repeat_factor ;
  7620.       begin
  7621.         -- we will enter this routine with the cursor pointing to the first
  7622.         -- character of the string that we want to match
  7623.         if verify_each_replacement then
  7624.           if not screen_is_not_erased then
  7625.             show_screen( master_buffer ) ;
  7626.             Screen_Is_Not_Erased := true ;  
  7627.           end if ;
  7628.           -- if not changed, then still Screen_Is_Not_Erased
  7629.           if repeat_factor = infinity then
  7630.             new_number := infinity ;
  7631.           else
  7632.             new_number := repeat_factor - number_found_so_far + 1 ;
  7633.           end if ;
  7634.           put_prompt("Replace",
  7635.                      "<reject> aborts, 'R' replaces, <space> doesn't",
  7636.                      new_number , false ) ;
  7637.           show_cursor( master_buffer ) ;
  7638.           get_c_or_cmd( User_Find_Character , User_Find_Editor_Command ) ;
  7639.           User_Find_Extended_Character := e_character ( User_Find_Character ) ;
  7640.           if (User_Find_Character /= 'R') 
  7641.           and (User_Find_Character /= 'r') then
  7642.             if (User_Find_Editor_Command = reject_command ) then
  7643.               raise reject_cmd ;
  7644.             else
  7645.               -- we need to set up for the next find
  7646.               if go_forward then
  7647.                 master_buffer.fixed_cursor.column_offset 
  7648.                   := master_buffer.fixed_cursor.column_offset + 1 ;
  7649.                   -- start one over for forward
  7650.               else
  7651.                 master_buffer.fixed_cursor.column_offset 
  7652.                   := master_buffer.fixed_cursor.column_offset - 1 ;
  7653.                   -- start one sooner for backwards 
  7654.               end if ;
  7655.               raise exit_replace_it ;
  7656.             end if ;
  7657.           end if ;
  7658.         end if ;
  7659.         -- replace The_Search_Target with The_Replacement_String
  7660.         -- first, we can set the old position because we will be sure of it
  7661.         Old_Find_Location.Line  := master_buffer.fixed_cursor.file_line_number;
  7662.         Old_Find_Location.Column:= master_buffer.fixed_cursor.column_offset ;
  7663.         added_length := Replacement_String_Length - Search_String_Length ; 
  7664.         -- how many added characters will there be
  7665.         if added_length > 0 then  -- adding characters
  7666.           -- make sure we have room for it
  7667.           -- since block size is guaranteed to be larger than the longest line
  7668.           --
  7669.           if master_buffer.bufcount + added_length >= max_buffer_size then
  7670.             -- must get rid of something...
  7671.             if master_buffer.fixed_cursor.line_start > block_size then
  7672.               -- do the top
  7673.               push_data( master_buffer , thetop , successfull ) ;
  7674.             else
  7675.               -- do the bottom
  7676.               push_data( master_buffer , thebot , successfull ) ;
  7677.             end if ;
  7678.             if successfull then
  7679.               fix_fixed_cursor ;
  7680.               un_fix_fixed_cursor ;
  7681.               -- to set up the buffer position correctly...
  7682.             else
  7683.               error("No Disk Space During Replace.", not_fatal_error ,
  7684.                     operator_wait , extra_short_beep   ) ;
  7685.               raise reject_cmd ;
  7686.             end if ;
  7687.           end if ;
  7688.           shift_buffer_area(master_buffer , 
  7689.                             master_buffer.fixed_cursor.buffer_position ,
  7690.                             master_buffer.fixed_cursor.buffer_position 
  7691.                                                                + added_length  ,
  7692.                             master_buffer.bufcount 
  7693.                             - master_buffer.fixed_cursor.buffer_position + 1 ) ;
  7694.         else
  7695.           shift_buffer_area(master_buffer , 
  7696.                             master_buffer.fixed_cursor.buffer_position
  7697.                                                         + Search_String_Length ,
  7698.                             master_buffer.fixed_cursor.buffer_position
  7699.                                                    + Replacement_String_Length ,
  7700.                             master_buffer.bufcount 
  7701.                             - ( master_buffer.fixed_cursor.buffer_position
  7702.                               + Search_String_Length ) + 1 ) ;
  7703.         end if ;
  7704.         -- now, modify the current line's length .....
  7705.         master_buffer.e_buf( Fixed_Cursor_Line_Start ).data
  7706.                     := extended_character(Lines_Text_Length + added_length ) ;
  7707.         Last_Line_Character_Position := Last_Line_Character_Position 
  7708.                                                         + added_length ;
  7709.         master_buffer.e_buf( Last_Line_Character_Position + 1 ).data
  7710.                     := extended_character(Lines_Text_Length + added_length ) ;
  7711.         master_buffer.bufcount := master_buffer.bufcount + added_length ;
  7712.           -- that is what the new buffer length is 
  7713.         for ind in 1 .. Replacement_String_Length loop
  7714.           master_buffer.e_buf( master_buffer.fixed_cursor.buffer_position
  7715.                       + ind - 1 ) := ( The_Replacement_String(ind) ,
  7716.                                        no_screen_attribute ) ; 
  7717.         end loop ;
  7718.         if added_length > 0 then
  7719.           Inserted_Range.Lo_Position 
  7720.             := Text_Position'( master_buffer.fixed_cursor.file_line_number ,
  7721.                                master_buffer.fixed_cursor.column_offset ,
  7722.                                no_screen_attribute ,
  7723.                                master_buffer ) ;
  7724.           Inserted_Range.Hi_Position
  7725.             := Text_Position'( master_buffer.fixed_cursor.file_line_number ,
  7726.                                master_buffer.fixed_cursor.column_offset 
  7727.                                                 + added_length ,
  7728.                                no_screen_attribute ,
  7729.                                master_buffer ) ;
  7730.           marker_manager.update_markers_for_added_text( master_buffer ,
  7731.                                                         inserted_range ) ;
  7732.         elsif added_length < 0 then
  7733.           -- deleted text 
  7734.           Inserted_Range.Lo_Position
  7735.             := Text_Position'( master_buffer.fixed_cursor.file_line_number ,
  7736.                                master_buffer.fixed_cursor.column_offset 
  7737.                                                    + Replacement_String_Length ,
  7738.                                no_screen_attribute ,
  7739.                                master_buffer ) ;
  7740.           Inserted_Range.Hi_Position
  7741.             := Text_Position'( master_buffer.fixed_cursor.file_line_number ,
  7742.                                master_buffer.fixed_cursor.column_offset
  7743.                                                         + Search_String_Length ,
  7744.                                no_screen_attribute ,
  7745.                                master_buffer ) ;
  7746.           marker_manager.update_markers_for_deleted_text( master_buffer ,
  7747.                                                         inserted_range ) ;
  7748.         -- else if the same length, do nothing...
  7749.         end if ;
  7750.         if go_forward then
  7751.           master_buffer.fixed_cursor.column_offset 
  7752.             := master_buffer.fixed_cursor.column_offset 
  7753.               + Search_String_Length + Replacement_String_Length - 1 ;
  7754.           -- the next possible place for the string
  7755.         else
  7756.           master_buffer.fixed_cursor.column_offset
  7757.             := master_buffer.fixed_cursor.column_offset  
  7758.               - Search_String_Length ;
  7759.           -- the next possible place on the left
  7760.         end if ;
  7761.           -- Note : going right we will offset by the substitution length,
  7762.           --        going left we offset by the The_Search_Target length !!
  7763.         Screen_Is_Not_Erased := false ;  
  7764.         -- we updated the page but the screen doesn't yet show
  7765.       exception 
  7766.         when exit_replace_it => null ;
  7767.       end replace_it ;
  7768.      
  7769.     begin -- do_find_command
  7770.       Old_Find_Location.Line   := master_buffer.fixed_cursor.file_line_number;
  7771.       Old_Find_Location.Column := master_buffer.fixed_cursor.column_offset   ;
  7772.       Last_Find_Location := Old_Find_Location ;
  7773.       if master_buffer.pagezero.tokdef then
  7774.         Find_Mode := Token_Mode ;
  7775.       else
  7776.         Find_Mode := Literal_Mode ;
  7777.       end if ;
  7778.       Do_A_Case_Sensitive_Search := master_buffer.pagezero.checkcase ;
  7779.       -- now scan for boundaries
  7780.       if Returned_Command = find_command then
  7781.         put_prompt("Find" , " <Target>  =>" , repeat_factor ) ;
  7782.       else
  7783.         put_prompt("Replace" ," V(erify <trgt> <substit> =>" , repeat_factor );
  7784.       end if ;
  7785.       need_prompt := true ;
  7786.       Get_Next_Character_Of_Find_Command ;
  7787.       Skip_Blanks ;
  7788.       if User_Find_Editor_Command = reject_command then
  7789.         raise reject_cmd ;
  7790.       end if ;
  7791.       Process_Command_Line_Options ;
  7792.       if User_Find_Editor_Command = reject_command then
  7793.         raise reject_cmd ;
  7794.       end if ;
  7795.       if Use_Last_Entered_String then
  7796.         -- move pstring to this target
  7797.         If search_target_defined then
  7798.           The_Search_Target := Search_Target ;
  7799.           Search_String_Length := Search_Target_Length ;
  7800.         else
  7801.           search_string_length := 0 ;
  7802.         end if ;
  7803.       else
  7804.         -- move this target to pstring
  7805.         parse_string( The_Search_Target , Search_String_Length ) ;
  7806.         if (User_Find_Editor_Command = reject_command ) then
  7807.           raise reject_cmd ;
  7808.         end if ;
  7809.         Search_Target := The_Search_Target ;
  7810.         Search_Target_Length := Search_String_Length ;
  7811.       end if ;
  7812.       Search_Target_Defined := ( Search_String_Length >= 1 ) ;
  7813.       if Search_Target_Defined then
  7814.         set_table ; -- once we have the word, set up the table for it
  7815.         compare_two ;
  7816.       end if ;
  7817.       if Returned_Command = replace_command then
  7818.         Get_Next_Character_Of_Find_Command ;
  7819.         Skip_Blanks ;
  7820.         if (User_Find_Editor_Command = reject_command ) then
  7821.           raise reject_cmd ;
  7822.         end if ;
  7823.         Use_Last_Entered_String := false ;
  7824.         Process_Command_Line_Options ;
  7825.         if Use_Last_Entered_String then
  7826.           -- move pstring to this target
  7827.           The_Replacement_String := Replace_String ;
  7828.           Replacement_String_Length := Replace_String_Length ;
  7829.         else
  7830.           -- move this target to pstring
  7831.           parse_string(The_Replacement_String,Replacement_String_Length) ;
  7832.           if User_Find_Editor_Command = reject_command then
  7833.             raise reject_cmd ;
  7834.           end if ;
  7835.           Replace_String := The_Replacement_String ;
  7836.           Replace_String_Length := Replacement_String_Length ;
  7837.           Replace_String_Defined := true ;
  7838.         end if ;
  7839.       end if ;
  7840.       clear_prompt(master_buffer) ;
  7841.       if (not Search_Target_Defined) 
  7842.       or (     ( not Replace_String_Defined   )
  7843.            and ( Returned_Command=replace_command ) ) then 
  7844.         error("No old pattern." , not_fatal_error ,
  7845.               operator_wait , extra_short_beep                );
  7846.       else
  7847.         Number_Found_So_Far := 0 ; -- have not found any yet
  7848.         -- first, we want to make sure that the Find instruction will not 
  7849.         -- find where we are now ...
  7850.         if returned_command = find_command then
  7851.           if go_forward then
  7852.             master_buffer.fixed_cursor.column_offset
  7853.                         := master_buffer.fixed_cursor.column_offset + 1 ;
  7854.           else
  7855.             master_buffer.fixed_cursor.column_offset
  7856.                         := master_buffer.fixed_cursor.column_offset - 1 ;
  7857.           end if ;
  7858.         end if ;
  7859.         loop 
  7860.           -- Now, we are sitting where we will allow the first letter of the
  7861.           -- string we are looking for.  Of course, for backwards, we will
  7862.           -- need to increment...etc.
  7863.           Find_The_Search_Target( Target_Found ) ; -- handles Token/Literal
  7864.           if target_found then
  7865.             Number_Found_So_Far := Number_Found_So_Far + 1 ;  
  7866.             -- we had to find one to get here
  7867.             Last_Find_Location.Line   
  7868.                         := master_buffer.fixed_cursor.file_line_number;
  7869.             Last_Find_Location.Column 
  7870.                         := master_buffer.fixed_cursor.column_offset   ;
  7871.             master_buffer.last_marked_position.data := last_find_location ;
  7872.             if returned_command = replace_command then
  7873.               replace_it ;
  7874.               if User_Find_Editor_Command = Reject_Command then
  7875.                 raise reject_cmd ;
  7876.               end if ;
  7877.             else
  7878.               Old_Find_Location := Last_Find_Location ;
  7879.               -- if we are just hopping over some, then we need to set
  7880.               -- the cursor position at the correct place...
  7881.               -- we will not allow the cursor to match to any part of this
  7882.               if go_forward then
  7883.                 master_buffer.fixed_cursor.column_offset
  7884.                         := master_buffer.fixed_cursor.column_offset 
  7885.                          + Search_String_Length ;
  7886.               else
  7887.                 If master_buffer.fixed_cursor.column_offset 
  7888.                             > search_string_length then 
  7889.                   master_buffer.fixed_cursor.column_offset
  7890.                           := master_buffer.fixed_cursor.column_offset 
  7891.                            - Search_String_Length ;
  7892.                 else
  7893.                   master_buffer.fixed_cursor.column_offset := 0 ;
  7894.                 end if ;
  7895.               end if ;
  7896.               -- only sets for find or actually changed replaced
  7897.             end if ;
  7898.           elsif (Number_Found_So_Far = 0)    -- nothing found this time
  7899.              or ( ( repeat_factor /= infinity ) 
  7900.               and (Number_Found_So_Far < repeat_factor) ) then
  7901.             not_enough_found ;
  7902.           end if ;
  7903.         exit when ( (Number_Found_So_Far >= repeat_factor) 
  7904.                   and (repeat_factor /= infinity ) ) 
  7905.                   or ( not target_found) ;
  7906.         end loop ;
  7907.       end if ;
  7908.       jump_to_position ( master_buffer ,
  7909.                          last_find_location.line ,
  7910.                          last_find_location.column ,
  7911.                          false ) ;
  7912.       current_leading := num_leading_spaces( master_buffer ,
  7913.                 master_buffer.fixed_cursor.line_start ) ;
  7914.       if master_buffer.fixed_cursor.column_offset <= current_leading then
  7915.         master_buffer.fixed_cursor.column_offset := current_leading + 1 ;
  7916.       end if ;
  7917.       If not screen_is_not_erased then
  7918.         show_screen( master_buffer ) ;
  7919.       end if ;
  7920.       show_cursor( master_buffer ) ;
  7921.     exception
  7922.       when reject_cmd => current_leading := num_leading_spaces( master_buffer ,
  7923.                                    master_buffer.fixed_cursor.line_start ) ;
  7924.                          if master_buffer.fixed_cursor.column_offset 
  7925.                            <= current_leading then
  7926.                            master_buffer.fixed_cursor.column_offset 
  7927.                              := current_leading + 1 ;
  7928.                          end if ;
  7929.                          If not screen_is_not_erased then
  7930.                            show_screen( master_buffer ) ;
  7931.                          end if ;
  7932.                          show_cursor( master_buffer ) ;
  7933.       when find_exit =>  null ;
  7934.     end do_find_command ;
  7935.  
  7936.   begin -- Editor_Find
  7937.     -- FINDREPL by SAIC/Clearwater Editor Find & Replace Comds 26 Dec 84
  7938.     for posn in extended_character loop
  7939.       Token_Kind( posn ) := posn ;
  7940.     end loop ;
  7941.     for posn in extended_character( character'pos('A') ) 
  7942.              .. extended_character( character'pos('Z') ) loop
  7943.       Token_Kind(posn) := kind_alpha_numeric ;
  7944.     end loop ;
  7945.     for posn in extended_character( character'pos('a') )
  7946.              .. extended_character( character'pos('z') ) loop
  7947.       Token_Kind(posn) := Kind_Alpha_Numeric ;
  7948.     end loop ;
  7949.     for posn in extended_character( character'pos('0') )
  7950.              .. extended_character( character'pos('9') ) loop
  7951.       Token_Kind(posn) := Kind_Alpha_Numeric ;
  7952.     end loop ;
  7953.   end Editor_Find ;
  7954.      
  7955.   --$$$- EDITFIND
  7956.  
  7957. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7958. --editmain
  7959. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  7960.  
  7961.   --$$$+ EDITMAIN
  7962.     
  7963.   --
  7964.   -- File 017
  7965.   --
  7966.   -- Editor Written By Robert S. Cymbalski
  7967.   --                   Science Applications International Corporation
  7968.   --                   Energy Systems Group
  7969.   --                   Ada Software Development Project Team
  7970.   --                   2280 U.S. Highway 19 North, Suite 120
  7971.   --                   Clearwater, Florida  33575
  7972.   --
  7973.   --
  7974.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  7975.   -- 
  7976.        
  7977.   with text_io                  ;  -- for a file close which is accomplished
  7978.                                    -- within the kill command
  7979.   with basic_io_system ;
  7980.    
  7981.   with string_library  ;
  7982.   use  string_library  ;
  7983.    
  7984.   with crt_customization ;
  7985.   use  crt_customization ;
  7986.   use  crt               ;
  7987.   use  editor_customization ;
  7988.    
  7989.   with crt_windows     ;
  7990.    
  7991.   with Wordp_Globals   ;
  7992.   use  Wordp_Globals   ;
  7993.  
  7994.   with editor_globals  ;
  7995.   use  editor_globals  ;
  7996.     
  7997.   with buffer_package  ;
  7998.   use  buffer_package  ;
  7999.   use  buffer_general  ;
  8000.   use  buffer_lines    ;
  8001.    
  8002.   with edit_windows             ;
  8003.   use  edit_windows             ;
  8004.     
  8005.   with markers                  ;
  8006.   use  markers                  ;
  8007.   use  text_position_handler    ;
  8008.     
  8009.   with editor_misc              ;
  8010.   use  editor_misc              ;
  8011.   use  copy_package ;
  8012.     
  8013.   package editor_main_packages is
  8014.     
  8015.     procedure do_adjust_command ;
  8016.       
  8017.     procedure do_end_open_commands ( how_to_end : in an_editor_command ) ;
  8018.       
  8019.     procedure do_kill_command( direction : in boolean ) ;
  8020.       
  8021.     procedure do_zap_command ;
  8022.       
  8023.     procedure do_printer_command ;
  8024.       
  8025.     allow_alternate_prompt_command : boolean := true ;
  8026.       
  8027.   end editor_main_packages ;
  8028.     
  8029.   package body editor_main_packages is 
  8030.     
  8031.     -- Printer_Device_Name : constant string := basic_io_system.printer_name ;
  8032.      
  8033.     Printer_Device_Name : constant string := "PRINTER:" ;
  8034.       
  8035.     procedure do_adjust_command is
  8036.       type mode_type is ( Relative , Left_Justify , Right_Justify , Center ) ;
  8037.       mode              : mode_type       ;
  8038.       amount_to_move_right : integer ;
  8039.       old_repeat_factor : a_repeat_factor ;
  8040.       new_repeat_factor : a_repeat_factor ;
  8041.       new_command       : an_editor_command ;
  8042.       lines_remaining   : integer ;
  8043.       
  8044.       procedure do_this_line ( current_amount : Integer ) is
  8045.         -- do the specified operation to the current line 
  8046.         Old_Leading_Spaces : integer ;
  8047.         leading_spaces : Integer ;
  8048.         lmarg , rmarg  : Integer ;
  8049.         Line_Leng      : Integer ;
  8050.         window_line    : integer ; -- because we make it and then see if it
  8051.                                    -- is a legal window_line_number ;
  8052.         changed_range  : text_range ;
  8053.       begin -- do_this_line 
  8054.         -- first, find out the leading spaces & other facts 
  8055.         old_leading_spaces := num_leading_spaces ( master_buffer , 
  8056.                                                master_buffer.fixed_cursor ) ;
  8057.         leading_spaces     := old_leading_spaces ;
  8058.         lmarg := master_buffer.pagezero.lmargin ;
  8059.         rmarg := master_buffer.pagezero.rmargin ;
  8060.         Line_Leng := line_length( master_buffer , 
  8061.                                   master_buffer.fixed_cursor.line_start ) ;
  8062.         -- then, figure the new leading spaces  
  8063.         case mode is
  8064.           when Relative       => leading_spaces := leading_spaces +
  8065.                                                         current_amount ;
  8066.           when Left_Justify   => leading_spaces := 0 ;
  8067.           when Right_Justify  => leading_spaces := rmarg - line_leng ;
  8068.           when Center         => leading_spaces := ( rmarg - lmarg 
  8069.                                                            - line_leng ) / 2 ;
  8070.         end case ;
  8071.         -- then, fix leading spaces if necessary
  8072.         if leading_spaces > type_leading_spaces'last then 
  8073.           leading_spaces:= type_leading_spaces'last ;
  8074.         elsif leading_spaces < 0 then
  8075.           leading_spaces := 0 ;
  8076.         end if ;
  8077.         -- now, set leading spaces
  8078.         master_buffer.e_buf( master_buffer.fixed_cursor.line_start + 1 ).data
  8079.                 := type_leading_spaces( leading_spaces ) ;
  8080.         -- Now, update markers for the changed text
  8081.         if leading_spaces /= old_leading_spaces then
  8082.           Changed_Range.Lo_Position.Line 
  8083.                       := master_buffer.fixed_cursor.file_line_number ;
  8084.           Changed_Range.Hi_Position.Line
  8085.                       := master_buffer.fixed_cursor.file_line_number ;
  8086.           Changed_Range.Lo_Position.Which_Buffer := Master_Buffer ;
  8087.           Changed_Range.Hi_Position.Which_Buffer := Master_Buffer ;
  8088.           if leading_spaces > old_leading_spaces then
  8089.             -- added text
  8090.             Changed_Range.Lo_Position.Column := old_leading_spaces + 1 ;
  8091.             Changed_Range.Hi_Position.Column := leading_spaces + 1 ;
  8092.             marker_manager.update_markers_for_added_text  
  8093.                                              ( master_buffer , changed_range ) ;
  8094.           else
  8095.             -- deleted text
  8096.             Changed_Range.Lo_Position.Column := Leading_Spaces + 1 ;
  8097.             Changed_Range.Hi_Position.Column := Old_Leading_Spaces + 1 ;
  8098.             marker_manager.update_markers_for_deleted_text
  8099.                                              ( master_buffer , changed_range ) ;
  8100.           end if ;
  8101.         end if ;
  8102.         -- and finally redisplay the line 
  8103.         master_buffer.fixed_cursor.column_offset := leading_spaces + 1 ;
  8104.         if cursor_off_screen(master_buffer) then
  8105.           show_cursor( master_buffer ) ; -- redraws screen 
  8106.         else
  8107.           window_line := master_buffer.fixed_cursor.file_line_number 
  8108.                        - master_buffer.top_screen_cursor.file_line_number + 1 ;
  8109.           clear_end_of_line ( master_buffer , window_line ,
  8110.                               lowest_column_number( master_buffer ) ) ;
  8111.           show_line ( master_buffer ,
  8112.                       master_buffer.fixed_cursor.line_start ,
  8113.                       master_buffer.fixed_cursor.file_line_number ) ; 
  8114.           show_cursor( master_buffer ) ;
  8115.         end if ;
  8116.       end do_this_line ;
  8117.         
  8118.     begin -- do_adjust_command 
  8119.       set_repeat_prompt( true , -1 ) ; 
  8120.       prompt( adjust_command_prompt ) ;
  8121.       -- set the last position
  8122.       marker_manager.load_marker( master_buffer.last_marked_position ,
  8123.                                   current_position ) ;
  8124.       Mode := Relative ;
  8125.       amount_to_move_right := 0 ;
  8126.       new_repeat_factor := ( -1 ) ;
  8127.       allow_alternate_prompt_command := false ;
  8128.       loop
  8129.         show_cursor( master_buffer ) ;
  8130.         -- first, get the next command 
  8131.         old_repeat_factor := new_repeat_factor ;
  8132.         get_next_command( old_repeat_factor, new_repeat_factor, new_command );
  8133.         If new_repeat_factor > max_column_number then
  8134.           new_repeat_factor := max_column_number  ; 
  8135.           -- we don't allow any funny business here
  8136.         end if ;
  8137.         -- note that the commands are locked into the definition shown in
  8138.         -- the crt package
  8139.         case new_command is
  8140.           when up_command       => lines_remaining := new_repeat_factor ;
  8141.                                    while ( lines_remaining > 0 ) 
  8142.                                    and then ( cursor_backward_line ) loop 
  8143.                                      do_this_line( amount_to_move_right ) ;
  8144.                                      lines_remaining := lines_remaining - 1 ;
  8145.                                    end loop ;
  8146.           when down_command     => lines_remaining := new_repeat_factor ;
  8147.                                    while ( lines_remaining > 0 ) 
  8148.                                    and then ( cursor_forward_line ) loop
  8149.                                      do_this_line( amount_to_move_right ) ;
  8150.                                      lines_remaining := lines_remaining - 1 ;
  8151.                                    end loop ;
  8152.           when right_command    => amount_to_move_right := 
  8153.                                      amount_to_move_right + new_repeat_factor ;
  8154.                                    If amount_to_move_right > max_column_number
  8155.                                                 then
  8156.                                      amount_to_move_right := max_column_number ;
  8157.                                    end if ;
  8158.                                    mode := relative ;
  8159.                                    do_this_line( new_repeat_factor )  ;
  8160.           when left_command     => amount_to_move_right := 
  8161.                                      amount_to_move_right - new_repeat_factor ;
  8162.                                    if amount_to_move_right < -max_column_number
  8163.                                                 then
  8164.                                      amount_to_move_right := -max_column_number;
  8165.                                    end if ;
  8166.                                    mode := relative ;
  8167.                                    do_this_line( - new_repeat_factor )  ;
  8168.           when copy_command     => mode := center ;
  8169.                                    amount_to_move_right := 0 ;
  8170.                                    do_this_line( amount_to_move_right ) ;
  8171.           when print_screen_command  => mode := left_justify ;
  8172.                                    amount_to_move_right := 0 ;
  8173.                                    do_this_line( amount_to_move_right ) ;
  8174.           when replace_command  => mode := right_justify ;
  8175.                                    amount_to_move_right := 0 ;
  8176.                                    do_this_line( amount_to_move_right ) ;
  8177.           when accept_command   => null ; 
  8178.           when others           => null ;
  8179.         end case ; 
  8180.       exit when new_command = accept_command ;
  8181.       end loop ;
  8182.       -- what do we have to do to finish up ? 
  8183.       need_prompt := true ; -- When we leave, we will have to re-prompt
  8184.       allow_alternate_prompt_command := true ;
  8185.     end do_adjust_command ;
  8186.       
  8187.     procedure do_kill_command ( direction : in boolean ) is
  8188.       -- only implemented for the forward direction.....
  8189.       cursor    : cursor_position      ;
  8190.       linestart : type_buffer_position ;
  8191.       buf_position : type_buffer_position ;
  8192.       leading_spaces : type_leading_spaces ;
  8193.       line      : line_number          ; 
  8194.       col       : column_position      ;
  8195.       line_leng : type_line_length     ;
  8196.       changed_range  : text_range ;
  8197.       
  8198.       procedure set_posn( posn : type_buffer_position ;
  8199.                           num  : integer              ) is
  8200.       begin
  8201.         master_buffer.e_buf(posn).data := extended_character( num ) ;
  8202.       end;
  8203.         
  8204.     begin -- do_kill_command 
  8205.       set_repeat_prompt( false , 0 ) ;
  8206.       prompt( kill_command_prompt ) ;
  8207.       if crt_windows.char_or_abort( 'N' , 'Y' , 'N' ) = 'Y' then
  8208.         -- To kill all following text, these steps must be taken...
  8209.         -- First, Tell the buffer that no more text can be read in from the 
  8210.         -- input file...
  8211.         master_buffer.still_reading_input_file := false ;
  8212.         if text_io.is_open(master_buffer.inputfile) then
  8213.           text_io.close(master_buffer.inputfile);
  8214.         end if ;
  8215.         -- Then, tell the buffer that no bottom blocks are waiting either...
  8216.         master_buffer.presbotblock := 0 ;
  8217.         -- Now, kill all text following us in our current buffer
  8218.         cursor         := master_buffer.fixed_cursor ;
  8219.         linestart      := cursor.line_start ;
  8220.         buf_position   := cursor.buffer_position ;
  8221.         leading_spaces := num_leading_spaces( master_buffer , linestart ) ;
  8222.         line           := cursor.file_line_number;
  8223.         col            := cursor.column_offset ;
  8224.         line_leng      := line_length( master_buffer , linestart ) ;
  8225.         -- find out if we are in leading spaces, text, or after all...
  8226.         if col <= leading_spaces then
  8227.           -- first possibility...easy to take care of...
  8228.           -- first, do buffer 
  8229.           set_posn( linestart     , 0 ) ; -- no text in line
  8230.           set_posn( linestart + 1 , col - 1 ) ; -- leading spaces 
  8231.           set_posn( linestart + 2 , 0 ) ; -- no text in line
  8232.           set_posn( linestart + 3 , buffer_boundry ) ; -- eof
  8233.           -- then set sizing...
  8234.           master_buffer.bufcount := linestart + 3 ;
  8235.           -- finally, do the cursor..
  8236.           master_buffer.fixed_cursor.buffer_position := 0 ;
  8237.         elsif col <= leading_spaces + line_leng then
  8238.           -- second possibility...in the text area
  8239.           -- first, do buffer 
  8240.           buf_position := linestart + col - leading_spaces + 1 ;
  8241.           set_posn( linestart     , col - leading_spaces - 1 ) ; 
  8242.                         -- only preceding text on line
  8243.           set_posn( buf_position  , col - leading_spaces - 1 ) ;
  8244.           set_posn( buf_position + 1 , buffer_boundry ) ; -- eof
  8245.           -- then set sizing...
  8246.           master_buffer.bufcount := buf_position + 1 ;
  8247.           -- finally, do the cursor..
  8248.           master_buffer.fixed_cursor.buffer_position := 0 ;
  8249.         else
  8250.           -- third possibility, following everything.....
  8251.           -- first, do buffer 
  8252.           buf_position := linestart + line_leng + 3 ;
  8253.           set_posn( buf_position , buffer_boundry ) ; -- eof
  8254.           -- then set sizing...
  8255.           master_buffer.bufcount := buf_position ;
  8256.           -- finally, do the cursor..
  8257.           master_buffer.fixed_cursor.buffer_position := 0 ;
  8258.         end if ;
  8259.         -- Next, adjust the markers.....
  8260.         Changed_Range.Lo_Position.Line         := line            ;
  8261.         Changed_Range.Lo_Position.Column       := col             ;
  8262.         Changed_Range.Lo_Position.Which_Buffer := Master_Buffer   ;
  8263.         Changed_Range.Hi_Position.Line         := max_line_number ;
  8264.         Changed_Range.Hi_Position.Column       := max_column_number ;
  8265.         Changed_Range.Hi_Position.Which_Buffer := Master_Buffer   ;
  8266.         marker_manager.update_markers_for_deleted_text
  8267.                                            ( master_buffer , changed_range ) ;
  8268.         -- Finally, redraw the screen...
  8269.         show_screen( master_buffer , master_buffer.fixed_cursor , 
  8270.                                      window_height( master_buffer ) ) ;
  8271.       end if ;
  8272.       need_prompt := true ;
  8273.     end do_kill_command ;
  8274.         
  8275.     procedure do_zap_command is
  8276.       -- delete the text from the zap marker to the current position
  8277.     begin -- do_zap_command 
  8278.       need_prompt := true ; -- When we leave, we will have to re-prompt
  8279.       set_repeat_prompt( false , 0 ) ; -- Turn off the counters... 
  8280.       prompt( zap_command_prompt ) ;
  8281.       if crt_windows.char_or_abort( 'N' , 'Y' , 'N' ) = 'Y' then
  8282.         -- then do the zap...
  8283.         copy_text_to_copy_buffer( master_buffer , 
  8284.                                   text_range'(
  8285.                                     master_buffer.last_marked_position.data , 
  8286.                                     current_position ,
  8287.                                     no_screen_attribute ) ,
  8288.                                   true ) ;
  8289.         show_screen( master_buffer ) ;
  8290.       end if ;
  8291.     end do_zap_command ;
  8292.       
  8293.     procedure do_printer_command is
  8294.       printer_file : text_io.file_type ;
  8295.       line_num     : integer ;
  8296.       old_cursor   : cursor_position ;
  8297.       Line_Of_Text : type_text_line  ;
  8298.       c            : character       ;
  8299.       -- note that the only reason that we are able to get away with simply
  8300.       -- saving and restoring the fixed_cursor is because we know that moving
  8301.       -- on the screen and up to one line later can NEVER push/pop the
  8302.       -- buffer....
  8303.     begin -- do_printer_command 
  8304.       set_repeat_prompt( false , 0 ) ;
  8305.       prompt( line_printer_command_prompt ) ;
  8306.       if crt_windows.char_or_abort( 'N' , 'Y' , 'N' ) = 'Y' then
  8307.         -- ready to print...
  8308.         prompt( " Copying Screen Data Area To The Printer " ) ;
  8309.         text_io.open(printer_file , text_io.out_file , printer_device_name ) ;
  8310.         line_num := 1 ;
  8311.         old_cursor := master_buffer.fixed_cursor ;
  8312.         master_buffer.fixed_cursor := master_buffer.top_screen_cursor ;
  8313.         loop
  8314.           -- show the cursor for fun...
  8315.           master_buffer.fixed_cursor.column_offset := 
  8316.                num_leading_spaces( master_buffer ,
  8317.                                    master_buffer.fixed_cursor.line_start ) + 1 ;
  8318.           show_cursor( master_buffer ) ;
  8319.           -- show the line... 
  8320.           get_text_line( master_buffer , master_buffer.fixed_cursor.line_start ,
  8321.                          Line_Of_Text  ) ;
  8322.           for posn in 1 .. line_of_text.data_length loop
  8323.             c := character'val( line_of_text.data(posn) mod 128 ) ;
  8324.             text_io.put( printer_file , c ) ;
  8325.           end loop ;
  8326.           text_io.new_line( printer_file ) ;
  8327.           line_num := line_num + 1 ;
  8328.         exit when line_num > window_height( master_buffer ) ;
  8329.         exit when not cursor_forward_line ;
  8330.         end loop ;
  8331.         text_io.close( printer_file ) ;
  8332.         master_buffer.fixed_cursor := old_cursor ;
  8333.       end if ;
  8334.       need_prompt := true ;
  8335.     exception
  8336.       when others => error(" Unable To Print " , 
  8337.                            not_fatal_error ,operator_wait ,short_beep ) ;
  8338.                      master_buffer.fixed_cursor := old_cursor ;
  8339.                      need_prompt := true ;
  8340.     end do_printer_command ;
  8341.       
  8342.     procedure do_end_open_commands ( how_to_end : in an_editor_command ) is
  8343.     begin -- do_end_open_commands 
  8344.       null;
  8345.     end do_end_open_commands ;
  8346.       
  8347.   begin -- Editor_Main_Packages
  8348.     -- EDITMAIN by SAIC/Clearwater Editor Main Packages        22 Jan 85
  8349.     -- ADJUST   by SAIC/Clearwater Editor Adjust Command       20 Feb 85
  8350.     -- DELETE   by SAIC/Clearwater Editor Delete/Kill/Zap/Acpt 21 Feb 85
  8351.     -- FINDREPL by SAIC/Clearwater Editor Find & Replace Comds 26 Dec 84
  8352.     -- PRINTER  by SAIC/Clearwater Editor Printer Command      22 Feb 85
  8353.     -- COMMAND  by SAIC/Clearwater Editor Command Interpretor  27 Dec 84
  8354.     null ;
  8355.   end Editor_Main_Packages ;
  8356.      
  8357.   --$$$- EDITMAIN
  8358. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8359. --editman2
  8360. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8361.  
  8362. --$$$+ EDITMAN2
  8363.    
  8364.   --
  8365.   -- File 020
  8366.   --
  8367.   -- Editor Written By Robert S. Cymbalski
  8368.   --                   Science Applications International Corporation
  8369.   --                   Energy Systems Group
  8370.   --                   Ada Software Development Project Team
  8371.   --                   2280 U.S. Highway 19 North, Suite 120
  8372.   --                   Clearwater, Florida  33575
  8373.   --
  8374.   --
  8375.   -- Revised from text Copyright (c) 1984 , R.S.Cymbalski
  8376.   -- 
  8377.    
  8378.   with Direct_IO    ;
  8379.    
  8380.   with string_library  ;
  8381.   use  string_library  ;
  8382.    
  8383.   with basic_io_system ;
  8384.    
  8385.   with crt_customization ;
  8386.   use  crt_customization ;
  8387.    
  8388.   with crt_windows     ;
  8389.    
  8390.   with Wordp_Globals   ;
  8391.   use  Wordp_Globals   ;
  8392.  
  8393.   with editor_globals         ;
  8394.   use  editor_globals         ;
  8395.    
  8396.   with edit_windows ;
  8397.   use  edit_windows ;
  8398.    
  8399.   with editor_misc  ;
  8400.   use  editor_misc  ;
  8401.    
  8402.   with markers      ;
  8403.   use  markers      ;
  8404.    
  8405.   with editor_Find  ;
  8406.   use  editor_find  ;
  8407.    
  8408.   package editor_more_packages is
  8409.    
  8410.     procedure do_help ( help_file : ascii_text_file_name ) ;
  8411.       -- use the designated file as a help file
  8412.      
  8413.     procedure do_help_command ;
  8414.      
  8415.     procedure do_set_information_command ;
  8416.      
  8417.     procedure shift_screen ( columns_to_move_right : in integer ) ;
  8418.      
  8419.     procedure do_verify_screen_command ;
  8420.      
  8421.     function get_marker_name return str10 ;
  8422.      
  8423.     function find_marker ( name : in str10 ) return marker_number ;
  8424.      
  8425.     procedure set_a_new_marker ;
  8426.       -- mark the current location with a new marker... and then give it
  8427.       -- a name...
  8428.    
  8429.     function jump_to_marker return text_position ;
  8430.       -- jump to a marker command
  8431.    
  8432.   end editor_more_packages ;
  8433.    
  8434.   package body editor_more_packages is
  8435.      
  8436.     block_size       : constant integer := 256 ; -- cannot be changed!
  8437.     subtype block_index is integer range 0 .. block_size - 1 ;
  8438.     type block_of_data is array ( block_index
  8439.                                   range 0 .. block_size - 1 ) of character ;
  8440.     type type_help_text_array is 
  8441.            record
  8442.              block_number : integer ;
  8443.              data         : block_of_data ;
  8444.            end record ;
  8445.             
  8446.     package help_file_io is new direct_io ( type_help_text_array ) ;
  8447.     -- unvalidated telesoft ada does not allow arrays, only records...
  8448.  
  8449.     procedure do_help ( help_file : ascii_text_file_name ) is
  8450.       -- use the designated file as a help file
  8451.       
  8452.       no_file_error   : exception ;
  8453.       help_file_error : exception ;
  8454.       get_block_error : exception ;
  8455.        
  8456.       key_list : crt_windows.character_set ;
  8457.        
  8458.       maximum_help_topics       : constant integer := 40 ; 
  8459.       subtype help_topic_index_number is INTEGER 
  8460.                                            range 1 .. maximum_help_topics ;
  8461.       subtype topic_name_type is string ( 1 .. 28 ) ;
  8462.       blank_topic_name : constant topic_name_type 
  8463.                                 := "                            " ;
  8464.       type help_topic_description is 
  8465.              record 
  8466.                block_number   : INTEGER range 0 .. 32000 := 0 ;
  8467.                place          : block_index              := 0 ;
  8468.                help_code      : CHARACTER                := ascii.nul ;
  8469.                topic_name     : topic_name_type          := blank_topic_name ;
  8470.              end record ; 
  8471.       type some_entries is array ( help_topic_index_number )
  8472.                                             of help_topic_description ;
  8473.       
  8474.       h_descript : some_entries ;
  8475.       first_text_block_in_file             : constant integer := 6 ;
  8476.       Help_Data_File            : help_file_io.FILE_TYPE ; 
  8477.       jump_table : array ( character ) of integer ;
  8478.       good_topics : integer ;
  8479.       next_c_place : block_index     ;
  8480.       subtype data_file_name is ascii_text_file_name ;
  8481.       master_option : character ;
  8482.       help_text_array : type_help_text_array ;
  8483.      
  8484.        
  8485.       procedure open_for_read ( file_handle : in out help_file_io.file_type ;
  8486.                                 file_name   : in out data_file_name        ) is
  8487.         -- Open the file setting the handle 
  8488.       begin -- open_for_read
  8489.         if help_file_io.is_open(file_handle) then
  8490.           help_file_io.close(file_handle);
  8491.         end if ;
  8492.         help_file_io.open(file_handle,help_file_io.inout_file,
  8493.                                       no_blanks(file_name));
  8494.       exception 
  8495.         when others                    => raise no_file_error  ;
  8496.       end open_for_read ;
  8497.        
  8498.       procedure get_block ( next_input_block : in out
  8499.                                                help_file_io.positive_count ) is
  8500.       begin -- get_block
  8501.         help_file_io.read ( Help_Data_File , help_text_array ,
  8502.                                              Next_Input_Block ) ;
  8503.         Next_Input_Block := Next_Input_Block + 1 ; 
  8504.         next_c_place := 0 ; 
  8505.       exception
  8506.         when others => raise Get_Block_Error ;
  8507.       end get_block ;
  8508.        
  8509.       procedure initialize is 
  8510.         type code_array_type is array ( 0 .. 
  8511.                   ( ( first_text_block_in_file - 1 ) * block_size ) - 1 )      
  8512.                           of character ;
  8513.         code_array : code_array_type ;
  8514.         i_block : help_file_io.positive_count ;
  8515.         final_name : data_file_name ;
  8516.          
  8517.         procedure convert_from_text_to_entry ( in_place : in integer ;
  8518.                                                t : out help_topic_description ) 
  8519.                                                is
  8520.         
  8521.           function int ( pla : integer ) return integer is
  8522.           begin
  8523.             return character'pos( code_array ( pla ) ) ;
  8524.           end;
  8525.            
  8526.         begin
  8527.           t.block_number := ( int( in_place + 00 ) * 64 )
  8528.                           + ( int( in_place + 01 ) / 2  ) ;
  8529.           t.place        := ( ( int( in_place + 01 ) mod 2 ) * 128)
  8530.                           + ( int( in_place + 02 ) ) ;
  8531.           t.help_code    := code_array ( in_place + 03 ) ;
  8532.           for posn in 1 .. 28 loop
  8533.             t.topic_name ( posn ) := code_array ( in_place + 3 + posn ) ;
  8534.           end loop ;
  8535.         end convert_from_text_to_entry ;
  8536.          
  8537.       begin -- initialize 
  8538.         final_name := help_file ;
  8539.         open_for_read ( help_data_file , final_name ) ;
  8540.         for blockn in 1 .. first_text_block_in_file - 1 loop
  8541.           i_block := help_file_io.positive_count ( blockn ) ;
  8542.           get_block ( i_block ) ;
  8543.           for posn in 0 .. block_size - 1 loop
  8544.             code_array ( (blockn-1) * block_size + posn ) := 
  8545.                                                 help_text_array.data(posn) ;
  8546.           end loop ;
  8547.         end loop ;
  8548.         crt_windows.clear_set ( key_list ) ;
  8549.         key_list(' ') := true ;
  8550.         for topic in 1 .. maximum_help_topics loop
  8551.           -- we must convert it over 
  8552.           convert_from_text_to_entry ( (topic-1)*32  ,
  8553.                                        h_descript( topic ) ) ;
  8554.           if h_descript ( topic ).help_code /= ascii.nul then
  8555.             key_list( h_descript(topic).help_code):= true ;
  8556.             good_topics := topic ;
  8557.             jump_table( h_descript(topic).help_code) := topic ;
  8558.           end if ;
  8559.         end loop ;
  8560.       end initialize ;
  8561.        
  8562.       procedure show_screen is
  8563.         j : integer ;
  8564.       begin -- show_screen
  8565.         clear_window ( master_buffer ) ;
  8566.         clear_prompt ( master_buffer ) ;
  8567.         goto_prompt_line_column ( master_buffer , 1 , 1 ) ;
  8568.         put(" The following help options are intended"
  8569.            &" as a quick reference to available com-" );
  8570.         goto_line_column( master_buffer , 1 , 1 ) ;
  8571.         put(" mands.  For further information, see th"
  8572.            &"e referenced section in the SAIC manual" );
  8573.         if good_topics < 17 then
  8574.           -- single column
  8575.           for topic in 1 .. good_topics loop
  8576.             goto_line_column( master_buffer , topic + 4 , 21 ) ;
  8577.             put( h_descript(topic).help_code & 
  8578.                   ") " & h_descript( topic ) .topic_name ) ;
  8579.           end loop ;
  8580.         else
  8581.           -- double column
  8582.           for topic in 1 .. ( good_topics + 1 ) / 2 loop
  8583.             goto_line_column( master_buffer , topic + 1 , 4 ) ;
  8584.             put( h_descript(topic).help_code & 
  8585.                   ") " & h_descript( topic ) .topic_name ) ;
  8586.           end loop ;
  8587.           j := 2 ;
  8588.           for topic in ( ( good_topics + 1 ) / 2 ) + 1 .. good_topics loop
  8589.             goto_line_column( master_buffer , j , 44 ) ;
  8590.             put( h_descript(topic).help_code & 
  8591.                   ") " & h_descript( topic ) .topic_name ) ;
  8592.             j := j + 1 ;
  8593.           end loop ;
  8594.         end if ;
  8595.         goto_line_column ( master_buffer , 23 , 22 );
  8596.         put("Enter Option (or <space> to quit) ? ");
  8597.       end show_screen ;
  8598.        
  8599.       procedure do_work is
  8600.         Next_Input_Block : help_file_io.POSITIVE_COUNT ;
  8601.         cur_topic : help_topic_index_number ;
  8602.         c : character ;
  8603.         
  8604.         procedure show_the_help_information is
  8605.           c : character ;
  8606.         begin -- show_the_help_information
  8607.           clear_window ( master_buffer ) ;
  8608.           clear_prompt ( master_buffer ) ;
  8609.           goto_prompt_line_column ( master_buffer , 1 , 1 ) ;
  8610.           loop
  8611.             c := help_text_array.data ( next_c_place ) ;
  8612.           exit when c = ascii.nul ;
  8613.             put(c);
  8614.             if next_c_place = block_size - 1 then
  8615.               get_block( next_input_block ) ; -- auto increment
  8616.             else
  8617.               next_c_place := next_c_place + 1 ;
  8618.             end if ;
  8619.           end loop ;
  8620.         end show_the_help_information ;
  8621.          
  8622.       begin -- do_work
  8623.         cur_topic := jump_table ( master_option ) ;
  8624.         loop
  8625.           next_input_block:= help_file_io.positive_count
  8626.                               (h_descript(cur_topic).block_number);
  8627.           get_block ( next_input_block ) ;
  8628.           next_c_place := h_descript(cur_topic).place ;
  8629.           show_the_help_information ;
  8630.           goto_line_column ( master_buffer , 23 , 27 ) ;
  8631.           put("Enter <space> to continue...");
  8632.           c := crt_windows.char_or_abort( ascii.cr , ascii.cr , ' ' ) ;
  8633.         exit when c = ' ' ;
  8634.           if cur_topic < maximum_help_topics then
  8635.             cur_topic := cur_topic + 1 ;
  8636.             if h_descript( cur_topic ) .help_code = ascii.nul then
  8637.               cur_topic := 1 ;
  8638.             end if ;
  8639.           else
  8640.             cur_topic := 1 ;
  8641.           end if ;
  8642.         end loop ;
  8643.       end do_work ;
  8644.        
  8645.       procedure finishup is
  8646.       begin -- finishup
  8647.         help_file_io.close ( Help_Data_File ) ;
  8648.       end finishup ;
  8649.        
  8650.       procedure error_message ( there_but_bad : boolean ) is
  8651.         c : character ;
  8652.       begin
  8653.         clear_window ( master_buffer ) ;
  8654.         clear_prompt ( master_buffer ) ;
  8655.         goto_line_column ( master_buffer , 5 , 5 ) ;
  8656.         put("The Desired Help File """ & compress( help_file ) & """ is ");
  8657.         if there_but_bad then
  8658.           put("damaged on your disk and is not available.");
  8659.           goto_line_column ( master_buffer , 7 , 5 ) ;
  8660.           put("Please erase it and replace it with a good copy from your "
  8661.               & "master backup.");
  8662.         else
  8663.           put("not on your disk.  Therefore,");
  8664.           goto_line_column( master_buffer , 7 , 5 ) ;
  8665.           put("this command is not available.");
  8666.         end if ;
  8667.         goto_line_column ( master_buffer , 10 , 5 ) ;
  8668.         put("Tap <space> to continue...");
  8669.         c := crt_windows.char_or_abort ( ' ' , ' ' ) ;
  8670.       end error_message ;
  8671.          
  8672.     begin -- do_help
  8673.       store_shift ;
  8674.       initialize ;
  8675.       loop
  8676.         show_screen ;
  8677.         master_option := crt_windows.goodchar ( key_list , ' ' ) ;
  8678.       exit when master_option = ' ' ;
  8679.         do_work ;
  8680.       end loop ;
  8681.       finishup ;
  8682.       restore_shift ;
  8683.     exception
  8684.       when help_file_error => error_message ( true ) ;
  8685.                               restore_shift ;
  8686.       when no_file_error   => error_message ( false) ;
  8687.                               restore_shift ;
  8688.       when get_block_error => error_message ( true ) ;
  8689.                               restore_shift ;
  8690.     end do_help ;
  8691.      
  8692.     procedure do_help_command is
  8693.     begin -- do_help_command 
  8694.       do_help ( Help_On_Editor_Commands_File_Name ) ;
  8695.     end do_help_command ;
  8696.      
  8697.     procedure change_environment ( buf : in out an_editor_buffer ;
  8698.                                    env : in out header           ) is
  8699.       -- allow the user to change the environment 
  8700.       environment_prompt : constant string ( 1 .. 61 ) :=
  8701. " Environment [options], ""?"" for Help, <space> or ""Q"" to Quit " ;
  8702.       prompt_column : constant integer := 65 ;
  8703.       change_option : character ;
  8704.      
  8705.       set_allowed_characters : constant crt_windows.character_set :=
  8706.                                   ( ascii.nul .. ascii.us => false ,
  8707.                                     ' '              => true  ,
  8708.                                     '!' .. '>'| '@'  => false ,
  8709.                                     '?' |
  8710.                                     'A' | 'B' | 'C' |
  8711.                                     'E' | 'F' | 'H' |
  8712.                                     'J' | 'L' | 'P' |
  8713.                                     'R' | 'S' | 'T' |
  8714.                                     'W'              => true  ,
  8715.                                     'Q'              => true  ,
  8716.                                     'D' | 'G' | 'I' |
  8717.                                     'K' | 'M' | 'N' |
  8718.                                     'O' | 'U' | 'V' |
  8719.                                     'X' .. ascii.del => false ) ;
  8720.        
  8721.       procedure bool ( b : boolean ) is
  8722.       begin
  8723.         if b then
  8724.           put_line("True ");
  8725.         else
  8726.           put_line("False");
  8727.         end if ;
  8728.       end bool ;
  8729.        
  8730.       procedure put ( d : basic_io_system.timer ) is
  8731.       begin -- put 
  8732.         case d.day_of_week is
  8733.           when basic_io_system.sunday     => put( "Sun" ) ;
  8734.           when basic_io_system.monday     => put( "Mon" ) ;
  8735.           when basic_io_system.tuesday    => put( "Tue" ) ;
  8736.           when basic_io_system.wednesday  => put( "Wed" ) ;
  8737.           when basic_io_system.thursday   => put( "Thu" ) ;
  8738.           when basic_io_system.friday     => put( "Fri" ) ;
  8739.           when basic_io_system.saturday   => put( "Sat" ) ;
  8740.         end case ;
  8741.         put(" ");
  8742.         case d.month is
  8743.           when  1 => put( "Jan" ) ;
  8744.           when  2 => put( "Feb" ) ;
  8745.           when  3 => put( "Mar" ) ;
  8746.           when  4 => put( "Apr" ) ;
  8747.           when  5 => put( "May" ) ;
  8748.           when  6 => put( "Jun" ) ;
  8749.           when  7 => put( "Jul" ) ;
  8750.           when  8 => put( "Aug" ) ;
  8751.           when  9 => put( "Sep" ) ;
  8752.           when 10 => put( "Oct" ) ;
  8753.           when 11 => put( "Nov" ) ;
  8754.           when 12 => put( "Dec" ) ;
  8755.         end case ;
  8756.         put(" ");
  8757.         put( d.day , 2 ) ;
  8758.         put(" ");
  8759.         put( d.year , 4 ) ;
  8760.         put(" ");
  8761.         put( d.hour , 2 ) ;
  8762.         put(":");
  8763.         if d.minute < 10 then
  8764.           put("0");
  8765.           put( d.minute , 1 ) ;
  8766.         else
  8767.           put( d.minute , 2 ) ;
  8768.         end if ;
  8769.       end put ;
  8770.        
  8771.       procedure long_put ( s : in a_target ; len : in search_target_index ) is
  8772.         -- put out the string, and show ascii.cr as <eol>
  8773.         -- we have only 67 columns to work with
  8774.         out_place : integer := 23 ;
  8775.         cur_char  : search_target_index := 1  ;
  8776.         in_string : boolean := false ;
  8777.         c         : character ;
  8778.       begin -- long_put
  8779.         loop
  8780.         exit when cur_char > len ;
  8781.           c := character'val( s(cur_char) ) ;
  8782.           if c = ascii.cr then
  8783.             -- an end of line
  8784.             if in_string then
  8785.               in_string := false ;
  8786.               put('"');
  8787.               out_place := out_place + 1 ;
  8788.             end if ;
  8789.             put(" <eol>");
  8790.             out_place := out_place + 6 ;
  8791.           else
  8792.             if not in_string then
  8793.               in_string := true ;
  8794.               put(" """);
  8795.               out_place := out_place + 2 ;
  8796.             end if ;
  8797.             put( c ) ;
  8798.             out_place := out_place + 1 ;
  8799.           end if ;
  8800.           cur_char := cur_char + 1 ;
  8801.         exit when out_place > 69 ;
  8802.         end loop ;
  8803.         if in_string then
  8804.           put('"');
  8805.         end if ;
  8806.         if cur_char <= len then
  8807.           put(" ...");
  8808.         end if ;
  8809.       end long_put ;
  8810.        
  8811.       procedure show_all is
  8812.       begin -- show_all
  8813.         clear_window( buf );
  8814.         goto_line_column ( buf , 2 , 1 ) ;
  8815.         -- First , show standard options 
  8816.         put("  A(uto Indent       "); bool( env.autoindent ) ;
  8817.         put("  B(reak Character   "); put ( env.break_char ) ; put_line ;
  8818.         put("  C(ase Sensitive    "); bool( env.checkcase  ) ;
  8819.         put("  E(nable Commands   "); bool( env.enable_cmds) ;
  8820.         put("  F(illing           "); bool( env.filling    ) ;
  8821.         put("  H(elp              ");                          put_line ;
  8822.         put("  J(ustify           "); bool( env.justify    ) ;
  8823.         put("  L(eft Margin       "); put ( env.lmargin , 3) ; put_line ;
  8824.         put("  P(aragraph Margin  "); put ( env.paramargin,3); put_line ;
  8825.         put("  R(ight Margin      "); put ( env.rmargin , 3) ; put_line ;
  8826.         put("  S(ave Environment  "); bool( env.save_envirn) ;
  8827.         put("  T(oken Mode        "); bool( env.tokdef     ) ;
  8828.         put("  W(ord Processor    "); bool( env.wordprocess) ;
  8829.         -- we just finished line 14
  8830.         -- Then, show targets
  8831.         goto_line_column ( buf , 16 , 3 ) ;
  8832.         put("Find Pattern    : ");
  8833.         if search_target_defined then
  8834.           long_put(search_target,search_target_length);
  8835.         else
  8836.           put("<None>");
  8837.         end if ;
  8838.         goto_line_column ( buf , 17 , 3 ) ;
  8839.         put("Replace Pattern : ");
  8840.         if replace_string_defined then
  8841.           long_put(replace_string,replace_string_length);
  8842.         else
  8843.           put("<None>");
  8844.         end if ;
  8845.         -- Then, show file names
  8846.         if buf.input_file_name /= no_file then
  8847.           goto_line_column( buf , 2 , 33 ) ;
  8848.           put("Input File     = ");
  8849.           put( compress( buf.input_file_name ) ) ;
  8850.         end if ;
  8851.         if buf.copy_file_name /= no_file then
  8852.           goto_line_column( buf , 3 , 33 ) ;
  8853.           put("Copied in file = ");
  8854.           put( compress( buf.copy_file_name ) ) ;
  8855.         end if ;
  8856.         if buf.output_file_name /= no_file then
  8857.           goto_line_column( buf , 4 , 33 ) ;
  8858.           put("Output File    = ");
  8859.           put( compress( buf.output_file_name ) ) ;
  8860.         end if ;
  8861.         -- Then, show memory usage
  8862.         goto_line_column( buf , 5 , 33 ) ;
  8863.         put("Characters in memory = ");
  8864.         put( buf.bufcount , 0 ) ;
  8865.         if buf.prestopblock > 0 then
  8866.           goto_line_column( buf , 6 , 33 ) ;
  8867.           put("Blocks before memory = ");
  8868.           put( buf.prestopblock , 0 ) ;
  8869.         end if ;
  8870.         if buf.presbotblock > 0 then
  8871.           goto_line_column( buf , 7 , 33 ) ;
  8872.           put("Blocks after memory  = ");
  8873.           put( buf.presbotblock , 0 ) ;
  8874.         end if ;
  8875.         goto_line_column( buf , 8 , 33 ) ;
  8876.         put("Characters per block = ");
  8877.         put( block_size , 0 ) ;
  8878.         if buf.still_reading_input_file then
  8879.           goto_line_column( buf , 9 , 33 ) ;
  8880.           put("Input file still being read in");
  8881.         end if ;
  8882.         goto_line_column( buf , 11 , 33 ) ;
  8883.         put("Cursor Line/Column = ");
  8884.         put( buf.fixed_cursor.file_line_number , 0 ) ;
  8885.         put(" / ");
  8886.         put( buf.fixed_cursor.column_offset , 0 ) ;
  8887.         -- Now, dates
  8888.         goto_line_column( buf , 13 , 33 ) ;
  8889.         put("Date Created      : ");
  8890.         put( env.created ) ;
  8891.         goto_line_column( buf , 14 , 33 ) ;
  8892.         put("Date Last Updated : ");
  8893.         put( env.last_used ) ;
  8894.         -- Finally, do the markers
  8895.         if env.marker_count > 0 then
  8896.           goto_line_column ( buf , 19 , 1 ) ;
  8897.           put("  Markers:  ");
  8898.           if env.marker_count < 7 then
  8899.             -- easy code for up to six markers 
  8900.             for marker_num in 1 .. env.marker_count loop
  8901.               goto_line_column ( buf , 19 +   ( marker_num - 1 )  /  2 ,
  8902.                                        13 + ( ( marker_num - 1 ) mod 2 ) * 40 );
  8903.               put( env.markers(marker_num).name ) ;
  8904.               put("  [ ");
  8905.               put( env.markers(marker_num).location.data.line , 5 ) ;
  8906.               put(" / ");
  8907.               put( env.markers(marker_num).location.data.column , 3 ) ;
  8908.               put(" ]");
  8909.             end loop ;
  8910.           elsif env.marker_count < 13 then 
  8911.             -- following code will work for up to 12 markers....
  8912.             for marker_num in 1 .. env.marker_count loop
  8913.               goto_line_column ( buf , 19 +   ( marker_num - 1 )  /  3 ,
  8914.                                        13 + ( ( marker_num - 1 ) mod 3 ) * 23 );
  8915.               put( env.markers(marker_num).name ) ;
  8916.               put(" ");
  8917.               put( env.markers(marker_num).location.data.line , 5 ) ;
  8918.               put("/");
  8919.               put( env.markers(marker_num).location.data.column , 3 ) ;
  8920.             end loop ;
  8921.           else
  8922.             -- here we will only show the names.  Leave it up to the
  8923.             -- person who changes the program to use more than that...
  8924.             null ;
  8925.           end if ;
  8926.         end if ;
  8927.         -- Don't forget the copyright notice -- This line must NOT be deleted 
  8928.         goto_line_column( buf , 23 , 1 ) ;
  8929.         put(
  8930. "SAIC Text Editor modified from Text Editor Copyright (c) 1984, R. S. Cymbalski"
  8931.           );
  8932.       end show_all ;
  8933.      
  8934.       procedure revbool ( line : in window_line_number   ;
  8935.                           col  : in window_column_number ;
  8936.                           b    : in out boolean          ) is
  8937.       begin -- revbool 
  8938.         goto_line_column ( buf , line , col ) ;
  8939.         b := not b ;
  8940.         bool ( b ) ;
  8941.       end revbool ;
  8942.        
  8943.       procedure get_brk ( line : in window_line_number   ;
  8944.                           col  : in window_column_number ;
  8945.                           c    : in out character        ) is
  8946.         new_c : character ;
  8947.       begin -- get_brk 
  8948.         goto_line_column ( buf , line , col ) ;
  8949.         new_c := crt_windows.char_within_range_or_abort ( '.' , '!' , '~' ) ;
  8950.         if new_c > ' ' then
  8951.           c := new_c ;
  8952.         end if ;
  8953.       end get_brk ;
  8954.        
  8955.       procedure getnumb ( line : in window_line_number   ;
  8956.                           col  : in window_column_number ;
  8957.                           n    : in out column_position  ) is
  8958.       begin -- getnumb 
  8959.         n := crt_windows.get_number( line , col , 0 ,
  8960.                                      column_position'last , 3 , n ) ;
  8961.       end getnumb ;
  8962.        
  8963.     begin -- change_environment 
  8964.       store_shift ;
  8965.       loop
  8966.         set_prompt( master_buffer , 1 , environment_prompt ) ;
  8967.         show_all ;
  8968.         loop
  8969.           goto_prompt_line_column( buf , 1 , prompt_column ) ;
  8970.           change_option := crt_windows.goodchar(set_allowed_characters , 'Q' ) ;
  8971.           case change_option is
  8972.             when 'A'    => revbool (  2 , 22 , env.autoindent ) ;
  8973.             when 'B'    => get_brk (  3 , 22 , env.break_char ) ; 
  8974.             when 'C'    => revbool (  4 , 22 , env.checkcase  ) ;
  8975.             when 'E'    => revbool (  5 , 22 , env.enable_cmds) ;
  8976.             when 'F'    => revbool (  6 , 22 , env.filling    ) ;
  8977.             when 'J'    => revbool (  8 , 22 , env.justify    ) ;
  8978.             when 'L'    => getnumb (  9 , 22 , env.lmargin    ) ;
  8979.             when 'P'    => getnumb ( 10 , 22 , env.paramargin ) ;
  8980.             when 'R'    => getnumb ( 11 , 22 , env.rmargin    ) ;
  8981.             when 'S'    => revbool ( 12 , 22 , env.save_envirn) ;
  8982.             when 'T'    => revbool ( 13 , 22 , env.tokdef     ) ;
  8983.             when 'W'    => revbool ( 14 , 22 , env.wordprocess) ;
  8984.                            if env.wordprocess then
  8985.                              env.first_five := "?????" ;
  8986.                            else
  8987.                              env.first_five := "-----" ;
  8988.                            end if ;
  8989.                            env.last_five := env.first_five ;
  8990.             when others => null ;
  8991.           end case ;
  8992.         exit when ( change_option = 'H' ) or ( change_option = '?' )
  8993.                or ( change_option = 'Q' ) or ( change_option = ' ' ) ;
  8994.         end loop ;
  8995.       exit when ( change_option = ' ' ) or ( change_option = 'Q' ) ;
  8996.         -- we can only get here on a help command....
  8997.         do_help ( Help_On_Environment_Commands_File_Name );
  8998.       end loop ;
  8999.       restore_shift ;
  9000.     end change_environment ;
  9001.      
  9002.     procedure mark_tabs is
  9003.       -- set the tab settings within the file
  9004.       last_line : window_line_number   := 0 ;
  9005.       last_col  : window_column_number := 0 ;
  9006.       mark_opt  : character ;
  9007.        
  9008.       procedure show_a_tab ( tab_number : integer ; the_tab : tabtypes ) is
  9009.         new_line : window_line_number ;
  9010.         new_col  : window_column_number ;
  9011.       begin -- show_a_tab
  9012.         if tab_number mod 100 < 50 then
  9013.           -- in the first set
  9014.           new_line := ( tab_number  /  100 ) +  4 ;
  9015.           new_col  := ( tab_number mod 100 ) + 10 ;
  9016.         else
  9017.           -- in the second set
  9018.           new_line := ( tab_number  /  100 ) + 14 ;
  9019.           new_col  := ( tab_number mod 100 ) + 20 - 50 ;
  9020.         end if ;
  9021.         if ( new_line /= last_line) or else ( new_col /= last_col ) then
  9022.           goto_line_column( master_buffer , new_line , new_col ) ;
  9023.         end if ;
  9024.         case the_tab is
  9025.           when tnone   => put(' ');
  9026.           when tnormal => put('T');
  9027.           when tnumber => put('N');
  9028.         end case ;
  9029.         last_line := new_line ;
  9030.         last_col  := new_col  + 1 ;
  9031.       end show_a_tab ;
  9032.          
  9033.       procedure show_tabs is
  9034.         line_num : integer ;
  9035.         a_number : integer ;
  9036.        
  9037.         procedure putit( number , position_to_show : integer ) is
  9038.           new_num : integer ;
  9039.         begin -- putit
  9040.           if position_to_show > 1 then
  9041.             new_num := number / position_to_show ;
  9042.           else
  9043.             new_num := number ;
  9044.           end if ;
  9045.           if ( new_num = 0 ) and then ( position_to_show /= 1 ) then
  9046.             -- the number is smaller than this, a leading zero 
  9047.             put(' ');
  9048.           else
  9049.             new_num := new_num mod 10 ;
  9050.             put(new_num,1);
  9051.           end if ;
  9052.         end putit ;
  9053.          
  9054.       begin
  9055.         -- clear the work area
  9056.         clear_window( master_buffer ) ;
  9057.         clear_prompt( master_buffer ) ;
  9058.         -- put the numbers across the top
  9059.         goto_line_column( master_buffer ,  1 , 10 ) ;
  9060.         for posn in  0 .. 49 loop
  9061.           putit( posn , 10 ) ;
  9062.         end loop ;
  9063.         goto_line_column( master_buffer , 11 , 20 ) ;
  9064.         for posn in 50 .. 99 loop 
  9065.           putit( posn , 10 ) ;
  9066.         end loop ;
  9067.         goto_line_column( master_buffer ,  2 , 10 ) ;
  9068.         for posn in  0 .. 49 loop
  9069.           putit( posn ,  1 ) ;
  9070.         end loop ;
  9071.         goto_line_column( master_buffer , 12 , 20 ) ;
  9072.         for posn in 50 .. 99 loop
  9073.           putit( posn ,  1 ) ;
  9074.         end loop ;
  9075.         goto_line_column( master_buffer ,  3 ,  9 ) ;
  9076.         for posn in 0 .. 50 loop        -- logically 0 .. 49 + 1 
  9077.           put("=");
  9078.         end loop ;
  9079.         goto_line_column( master_buffer , 13 , 19 ) ;
  9080.         for posn in 50 .. 100 loop      -- logically 0 .. 99 + 1 
  9081.           put("=");
  9082.         end loop ;
  9083.         -- Now, show the left numbers
  9084.         a_number := 0 ;
  9085.         line_num := 4 ;
  9086.         while a_number <= column_position'last loop
  9087.           goto_line_column( master_buffer , line_num ,  3 ) ;
  9088.           put( a_number , 5 ) ;
  9089.           put(" |");
  9090.           line_num := line_num + 1 ;
  9091.           a_number := a_number + 100 ;
  9092.         end loop ;
  9093.         a_number :=  0 ;
  9094.         line_num := 14 ;
  9095.         while a_number <= column_position'last loop
  9096.           goto_line_column( master_buffer , line_num , 13 ) ;
  9097.           put( a_number , 5 ) ;
  9098.           put(" |");
  9099.           line_num := line_num + 1 ;
  9100.           a_number := a_number + 100 ;
  9101.         end loop ;
  9102.         -- and blank out position 0
  9103.         goto_line_column( master_buffer ,  4 , 10 ) ;
  9104.         put("X");
  9105.         -- Now, show the tabs
  9106.         last_line := 0 ;
  9107.         last_col  := 0 ;
  9108.         for posn in 1 .. column_position'last loop
  9109.           show_a_tab( posn , master_buffer.pagezero.tabline(posn) ) ;
  9110.         end loop ;
  9111.       end show_tabs ;
  9112.      
  9113.       procedure set_single_tab is
  9114.         new_location : integer   ;
  9115.         def          : character ;
  9116.         tb           : tabtypes  ;
  9117.       begin -- set_single_tab
  9118.         loop
  9119.           clear_end_of_screen( master_buffer , 21 , 1 ) ;
  9120.           goto_line_column( master_buffer , 22 , 1 ) ;
  9121.           put("  Enter Column Number To Set/Reset Tab (<return> to exit) => ");
  9122.           new_location := crt_windows.get_number( 22 , 62 , 1 , 
  9123.                                                   column_position'last ,3,0);
  9124.         exit when new_location = 0 ;
  9125.           -- we are here with a good tab position 
  9126.           clear_end_of_screen( master_buffer , 21 , 1 ) ;
  9127.           goto_line_column( master_buffer , 22 , 1 ) ;
  9128.           put(" Current Setting at position #");
  9129.           put(new_location,3);
  9130.           put(" Is """);
  9131.           tb := master_buffer.pagezero.tabline(new_location);
  9132.           case tb is
  9133.             when tnone    => put("No");      def := ' ' ;
  9134.             when tnumber  => put("Numeric"); def := 'N' ;
  9135.             when tnormal  => put("Normal");  def := 'T' ;
  9136.           end case ;
  9137.           put(" Tab"".");
  9138.           goto_line_column( master_buffer , 23 , 1 ) ;
  9139.           put(
  9140. " Enter 'T' for normal tab, <space> to delete tab, or 'N' for numeric tab ? ");
  9141.           case crt_windows.char_or_abort( def , ' ' , 'T' , 'N' ) is
  9142.             when ' '    => tb := tnone ;
  9143.             when 'T'    => tb := tnormal ;
  9144.             when 'N'    => tb := tnumber ;
  9145.             when others => null ;
  9146.           end case ;
  9147.           master_buffer.pagezero.tabline(new_location) := tb ;
  9148.           show_a_tab( new_location , tb ) ;
  9149.         end loop ;
  9150.       end set_single_tab ;
  9151.        
  9152.     begin -- mark_tabs
  9153.       store_shift ;
  9154.       loop
  9155.         -- first, show the old tabs
  9156.         show_tabs ;
  9157.         -- now, show the instructions 
  9158.         goto_line_column( master_buffer , 20 , 1 ) ;
  9159.         put("  The above tab settings are in effect.  ");
  9160.         -- and get the commands
  9161.         loop
  9162.           clear_end_of_screen( master_buffer , 21 , 1 ) ;
  9163.           goto_line_column( master_buffer , 22 , 1 ) ;
  9164.           put(
  9165.              "  Options: C(lear tabs, R(eset tabs, S(et tabs, H(elp, Q(uit ? ");
  9166.           mark_opt := 
  9167.                 crt_windows.char_or_abort( 'Q' , 'C','R','S','H','Q','?',' ' ) ;
  9168.           if mark_opt = ' ' then
  9169.             mark_opt := 'Q' ;
  9170.           end if ;
  9171.           last_line := 0 ;
  9172.           last_col  := 0 ;
  9173.           case mark_opt is
  9174.             when 'C'    => for posn in 1 .. column_position'last loop
  9175.                              master_buffer.pagezero.tabline(posn) := tnone ;
  9176.                              show_a_tab( posn , master_buffer.pagezero.
  9177.                                                     tabline(posn) ) ;
  9178.                            end loop ;
  9179.             when 'R'    => for posn in 1 .. column_position'last loop
  9180.                              if posn mod 8 = 1 and then
  9181.                                posn > 1 then
  9182.                                  master_buffer.pagezero.tabline(posn):=tnormal ;
  9183.                              else
  9184.                                master_buffer.pagezero.tabline( posn ):=tnone   ;
  9185.                              end if ;
  9186.                              show_a_tab( posn , master_buffer.pagezero.
  9187.                                                     tabline(posn) ) ;
  9188.                            end loop ;
  9189.             when 'S'    => set_single_tab ;
  9190.             when others => null ; -- handled outside this
  9191.           end case ;
  9192.         exit when ( mark_opt = 'Q' ) or ( mark_opt = 'H' ) or ( mark_opt = '?');
  9193.         end loop ;
  9194.       exit when mark_opt = 'Q' ;
  9195.         -- can only get here on a help request...
  9196.         do_help ( help_on_set_commands_file_name ) ;
  9197.       end loop ;
  9198.       restore_shift ;
  9199.     end mark_tabs ;
  9200.      
  9201.     procedure set_zap_marker is
  9202.     begin -- set_zap_marker 
  9203.       -- setting master_buffer.last_marked_position 
  9204.       marker_manager.load_marker( master_buffer.last_marked_position ,
  9205.                                   current_position ) ;
  9206.     end set_zap_marker ;
  9207.      
  9208.     procedure do_set_information_command is
  9209.     begin -- do_set_information_command 
  9210.       set_prompt( master_buffer , 1 , editor_customization.set_command_prompt );
  9211.       case crt_windows.char_or_abort( ' ' , ' ' , 'E' , 'M' , 
  9212.                                       'T' , 'Z' , 'H' , '?' ) is
  9213.         when 'E'       => change_environment ( master_buffer , 
  9214.                                                master_buffer.pagezero ) ;
  9215.                           show_screen( master_buffer, 
  9216.                                                 master_buffer.fixed_cursor, 0 );
  9217.         when 'M'       => set_a_new_marker   ;
  9218.         when 'T'       => mark_tabs;
  9219.                           show_screen( master_buffer, 
  9220.                                                 master_buffer.fixed_cursor, 0 );
  9221.         when 'Z'       => set_zap_marker     ;
  9222.         when 'H'       => do_help ( Help_On_Set_Commands_File_Name ) ;
  9223.                           show_screen( master_buffer, 
  9224.                                                 master_buffer.fixed_cursor, 0 );
  9225.         when others    => null     ;
  9226.       end case ;
  9227.       need_prompt := true ; -- we need to reprompt after this...
  9228.     end do_set_information_command ;
  9229.      
  9230.     procedure shift_screen ( columns_to_move_right : in integer ) is
  9231.     begin -- shift_screen 
  9232.       shift( master_buffer , columns_to_move_right ) ;
  9233.       show_screen( master_buffer, master_buffer.fixed_cursor , 0 ) ;
  9234.     end shift_screen ;
  9235.      
  9236.     procedure do_verify_screen_command is
  9237.     begin -- do_verify_screen_command
  9238.       need_prompt := true ;
  9239.       show_screen( master_buffer, master_buffer.fixed_cursor, 
  9240.                    window_height(master_buffer) / 2 );
  9241.     end do_verify_screen_command ;
  9242.      
  9243.     function get_marker_name return str10 is
  9244.       format    ,
  9245.       default   ,
  9246.       new_marker : pstring ;
  9247.       final_marker : str10 := "          " ;
  9248.     begin -- get_marker_name 
  9249.       format := string_to_pstring(blank_marker);
  9250.       default:= string_to_pstring(blank_marker);
  9251.       new_marker := crt_windows.
  9252.                            string_read( format , default , 0 , 0 , 0 , false ) ;
  9253.       new_marker := compress( new_marker ) ;
  9254.       -- that got rid of leading spaces
  9255.       final_marker := blank_marker ;
  9256.       for posn in 1 .. length( new_marker ) loop
  9257.         final_marker ( posn ) := new_marker.data ( posn ) ;
  9258.       end loop ;
  9259.       return final_marker ;
  9260.     end get_marker_name ;
  9261.      
  9262.     function find_marker ( name : in str10 ) return marker_number is
  9263.     begin -- find_marker
  9264.       for posn in 1 .. master_buffer.pagezero.marker_count loop
  9265.         if name = master_buffer.pagezero.markers ( posn ) . name then
  9266.           return posn ;
  9267.         end if ;
  9268.       end loop ;
  9269.       return 0 ;
  9270.     end find_marker ;
  9271.      
  9272.     procedure set_a_new_marker is
  9273.       -- mark the current location with a new marker... and then give it
  9274.       -- a name...
  9275.       target_marker : str10 ;
  9276.       the_marker_number : marker_number ;
  9277.       new_posn          : character     ;
  9278.     begin -- set_a_new_marker
  9279.       set_prompt( master_buffer , 1 ,
  9280.             " What is the new marker's name => " ) ;
  9281.       target_marker := get_marker_name ;
  9282.       if target_marker /= blank_marker then
  9283.         the_marker_number := find_marker( target_marker ) ;
  9284.         if the_marker_number > 0 then
  9285.           -- marker not found...
  9286.           set_prompt( master_buffer , 1 ,
  9287.                " Marker """ & compress(target_marker)
  9288.                        & """ already exists.  Reset its location (Y/N) ? ");
  9289.           if crt_windows.char_or_abort ( 'N' , 'Y' , 'N' ) = 'Y' then
  9290.             -- ok to reset its location
  9291.             marker_manager.load_marker( master_buffer.pagezero.markers
  9292.                                         ( the_marker_number ) .location ,
  9293.                                         current_position                ) ;
  9294.             master_buffer.pagezero.markers(the_marker_number).name
  9295.                                           := target_marker ;
  9296.           end if ;
  9297.         else
  9298.           -- we are ready to set a new marker in the list 
  9299.           if master_buffer.pagezero.marker_count < max_markers then
  9300.             the_marker_number := master_buffer.pagezero.marker_count + 1 ;
  9301.             marker_manager.new_marker ( master_buffer.pagezero.markers
  9302.                                         ( the_marker_number ) .location ) ;
  9303.             marker_manager.load_marker( master_buffer.pagezero.markers
  9304.                                         ( the_marker_number ) .location ,
  9305.                                         current_position                ) ;
  9306.             master_buffer.pagezero.markers(the_marker_number).name
  9307.                                           := target_marker ;
  9308.             master_buffer.pagezero.marker_count := the_marker_number ;
  9309.           else
  9310.             -- no room for more markers...
  9311.             Clear_window( master_buffer ) ;
  9312.             goto_line_column( master_buffer , 3 , 1 ) ;
  9313.             for posn in 1 .. max_markers loop
  9314.               put("            ");
  9315.               put( character'val( posn + 64 ) ) ;
  9316.               put(")  ");
  9317.               put( master_buffer.pagezero.markers(posn).name ) ;
  9318.               put_line ;
  9319.             end loop ;
  9320.             set_prompt( master_buffer , 1 , 
  9321. " Too many Markers.  Replace which one (or <Reject> to cancel new marker) ? ");
  9322.             new_posn := crt_windows.char_within_range_or_abort( 
  9323.                           ascii.nul , 'A' , character'val( max_markers + 64 )) ;
  9324.             if new_posn >= 'A' then
  9325.               -- we want to do something... 
  9326.               the_marker_number := character'pos( new_posn ) - 64 ;
  9327.               marker_manager.load_marker( master_buffer.pagezero.markers
  9328.                                         ( the_marker_number ) .location ,
  9329.                                         current_position                ) ;
  9330.               master_buffer.pagezero.markers(the_marker_number).name
  9331.                                           := target_marker ;
  9332.             end if ;
  9333.             show_screen ( master_buffer, master_buffer.fixed_cursor , 0 ) ;
  9334.           end if ;
  9335.         end if ;
  9336.       end if ;
  9337.     end set_a_new_marker ;
  9338.      
  9339.     function jump_to_marker return text_position is 
  9340.       -- jump to a marker command
  9341.       target_marker : str10 ;
  9342.       the_marker_number : marker_number ;
  9343.     begin -- jump_to_marker 
  9344.       set_prompt( master_buffer , 1 , " Jump to which marker => " ) ;
  9345.       target_marker := get_marker_name ;
  9346.       if target_marker /= blank_marker then
  9347.         the_marker_number := find_marker( target_marker ) ;
  9348.         if the_marker_number = 0 then
  9349.           -- marker not found...
  9350.           error(" Marker """ & compress(target_marker)
  9351.                         & """ Not Found In Marker List. ",
  9352.                 not_fatal_error , operator_wait , short_beep ) ;
  9353.           return no_set_location ;
  9354.         else
  9355.           return master_buffer.pagezero.markers(the_marker_number)
  9356.                                   .location .data ;
  9357.         end if ;
  9358.       else
  9359.         return no_set_location ;
  9360.       end if ;
  9361.     end jump_to_marker ;
  9362.      
  9363.   begin -- editor_more_packages
  9364.     -- EDITMAN2 by SAIC/Clearwater More Main Editor Packages   26 Dec 84
  9365.     -- HELP     by SAIC/Clearwater Help Package                31 Dec 84
  9366.     -- SET      by SAIC/Clearwater Set Package                 31 Dec 84
  9367.     -- SCREEN   by SAIC/Clearwater Screen Control Package      23 Jan 85
  9368.     -- UMARKER  by SAIC/Clearwater User's Marker Package       22 Jan 85
  9369.     null ;
  9370.   end editor_more_packages ;
  9371.     
  9372.   --$$$- EDITMAN2
  9373.  
  9374. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  9375. --editman3
  9376. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  9377.  
  9378. --$$$+ EDITMAN3
  9379.   -- Editor Revised from text Copyright (c) 1984 , R.S.Cymbalski
  9380.     
  9381.   with string_library, crt_customization, crt_windows ;
  9382.   with Wordp_Globals , editor_globals , edit_windows ;
  9383.   with buffer_package , editor_misc , markers ;
  9384.    
  9385.   use  string_library, crt_customization;
  9386.   use  crt , editor_customization;
  9387.   use  Wordp_Globals , editor_globals , edit_windows ;
  9388.   use buffer_package ;
  9389.   use buffer_general , buffer_lines ;
  9390.   use  editor_misc , markers ;
  9391.     
  9392.   package editor_even_more_packages is
  9393.     
  9394.     procedure do_justify ( txt : in out type_text_line ) ;
  9395.       -- justify single line...
  9396.      
  9397.     procedure do_re_margin_command ( start_position : cursor_position ;
  9398.                                      do_whole_paragraph : boolean := true ;
  9399.                                      number_of_paragraphs : integer := 1 ) ;
  9400.       
  9401.     procedure do_enter_exchange_mode ;
  9402.       
  9403.   end editor_even_more_packages ;
  9404.     
  9405.   package body editor_even_more_packages is
  9406.       
  9407.     a_space    : constant extended_character := 
  9408.                             extended_character( character'pos(' ') ) ;
  9409.     a_hyphen   : constant extended_character :=
  9410.                             extended_character( character'pos('-') ) ;
  9411.      
  9412.     procedure put( c : extended_character ) is
  9413.     begin -- put 
  9414.       put( character'val( c ) ) ;
  9415.     end put ;
  9416.       
  9417.     procedure do_justify ( txt : in out type_text_line ) is
  9418.       how_many_spaces_to_justify    : integer := 0 ;
  9419.       how_many_breaks_between_words : integer := 0 ;
  9420.       how_many_spaces_to_add_to_each_word_space : integer := 0 ;
  9421.       how_many_word_spaces_to_add_an_extra_space_to   : integer := 0 ;
  9422.       posn  : integer ;
  9423.       last_printable_text : type_text_length ;
  9424.       new_location        : type_text_length ;
  9425.       old_location        : type_text_length ;
  9426.       trailing_blanks     : integer  ;
  9427.       leading_spaces : type_leading_spaces ;
  9428.       first_text : type_text_length ;
  9429.       last_text  : type_text_length ;
  9430.       ln_length  : type_line_length ;
  9431.       -- later consider tieing markers to exact chars, even during justification
  9432.      
  9433.       procedure one_back is
  9434.       begin -- one_back
  9435.         txt.data(new_location) := txt.data(old_location) ;
  9436.         new_location := new_location - 1 ;
  9437.         old_location := old_location - 1 ;
  9438.       end one_back ;
  9439.        
  9440.       procedure add_spaces is
  9441.       begin -- add_spaces
  9442.         for add_a_space in 1..how_many_spaces_to_add_to_each_word_space loop
  9443.           txt.data(new_location) := a_space ;
  9444.           new_location := new_location - 1 ;
  9445.         end loop ;
  9446.         if how_many_word_spaces_to_add_an_extra_space_to > 0 then
  9447.           how_many_word_spaces_to_add_an_extra_space_to 
  9448.                 := how_many_word_spaces_to_add_an_extra_space_to - 1 ;
  9449.           txt.data(new_location) := a_space ;
  9450.           new_location := new_location - 1 ;
  9451.         end if ;
  9452.       end add_spaces ;
  9453.        
  9454.     begin -- do_justify
  9455.       get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  9456.       posn := last_text ;
  9457.       -- find last non-blank
  9458.       loop
  9459.       exit when posn <= first_text ; -- don't do anything
  9460.       exit when txt.data(posn) /= a_space;
  9461.         posn := posn - 1 ;
  9462.       end loop ;
  9463.       if posn > first_text then
  9464.         -- ok, we have something to work on, a word on a multi word line
  9465.         last_printable_text := posn ;
  9466.         how_many_spaces_to_justify := master_buffer.pagezero.rmargin
  9467.                                       - last_printable_text ;
  9468.         if how_many_spaces_to_justify > 0 then
  9469.           -- must do the work.  Count the word spaces 
  9470.           while posn > first_text loop
  9471.             posn := posn - 1 ;
  9472.             loop
  9473.             exit when posn = first_text
  9474.             or else txt.data(posn) = a_space ;
  9475.               posn := posn - 1 ;
  9476.             end loop ;
  9477.             if posn > first_text then
  9478.               loop
  9479.                 posn := posn - 1 ;
  9480.               exit when posn = first_text 
  9481.               or else txt.data(posn) /= a_space ;
  9482.               end loop ;
  9483.               how_many_breaks_between_words 
  9484.                           := how_many_breaks_between_words + 1 ;
  9485.             end if ;
  9486.           end loop ;
  9487.           -- ok, we know the number of word spaces and number of spaces
  9488.           if how_many_breaks_between_words > 0 then
  9489.             -- needed to justify the line 
  9490.             how_many_spaces_to_add_to_each_word_space       
  9491.              := how_many_spaces_to_justify   / how_many_breaks_between_words ;
  9492.             how_many_word_spaces_to_add_an_extra_space_to   
  9493.              := how_many_spaces_to_justify mod how_many_breaks_between_words ;
  9494.             -- work with last_text to move right
  9495.             -- work with last_printable text to begin searching for ' '
  9496.             new_location := master_buffer.pagezero.rmargin ;
  9497.             -- what about a lot of trailing blanks....
  9498.             trailing_blanks := last_text - last_printable_text ;
  9499.             if new_location + trailing_blanks >= type_text_length'last then
  9500.               -- must truncate some
  9501.               trailing_blanks := type_text_length'last - new_location - 1 ;
  9502.               last_text := last_printable_text + trailing_blanks ;
  9503.             end if ;
  9504.             new_location := new_location + trailing_blanks ;
  9505.             txt.data_length := new_location ;
  9506.             old_location := last_text ;
  9507.             -- now, start moving over...
  9508.             while new_location /= old_location loop
  9509.               -- become identical when we have moved far enough back 
  9510.               while txt.data(old_location) = a_space loop
  9511.                 one_back ;
  9512.               end loop ;
  9513.               while txt.data(old_location) /= a_space loop
  9514.                 one_back ;
  9515.               end loop ;
  9516.             exit when new_location = old_location ;
  9517.             add_spaces ;
  9518.             end loop ;
  9519.           -- else no word spaces to work with to justify
  9520.           end if ;
  9521.         -- else already justified or else a very long line...
  9522.         end if ;
  9523.       -- else blank line...
  9524.       end if ;
  9525.     end do_justify ;
  9526.        
  9527.     procedure do_re_margin_command ( start_position : cursor_position ;
  9528.                                      do_whole_paragraph : boolean := true ;
  9529.                                      number_of_paragraphs : integer := 1 ) is
  9530.       margin_command_prompt : constant string ( 1 .. 23 ) 
  9531.                                       := "Re-Filling Paragraph..." ;
  9532.       paragraphs_remaining : integer := number_of_paragraphs ;
  9533.       orig_text            : type_text_line ;
  9534.       leading    : type_leading_spaces ;
  9535.       text_first ,
  9536.       text_last  : type_text_length    ;
  9537.       text_leng  : type_line_length    ;
  9538.       end_of_file: exception           ;
  9539.       called_on_command_line : exception ;
  9540.       input_line_number ,
  9541.       output_line_number : line_number ;
  9542.       cursor_col : integer ;
  9543.       a_break_char:constant extended_character :=
  9544.                               extended_character( character'pos(
  9545.                                   master_buffer.pagezero.break_char ) ) ;
  9546.       orig_cursor_location : constant 
  9547.                              cursor_position := master_buffer.fixed_cursor ;
  9548.      
  9549.       function load_current_text ( pos : type_buffer_position ) 
  9550.                                    return boolean is
  9551.         len : integer ;
  9552.       begin -- load_current_text
  9553.         if master_buffer.e_buf(pos).data = buffer_boundry then
  9554.           orig_text.data_length := 0 ;
  9555.           return false ;
  9556.         else
  9557.           get_text_line( master_buffer , pos , orig_text ) ;
  9558.           for posn in orig_text.data_length + 1 .. max_column_number loop
  9559.             orig_text.data(posn) := extended_character(32); -- spaces...
  9560.           end loop ;
  9561.           get_leading ( orig_text, leading, text_first, text_last, text_leng ) ;
  9562.           len := orig_text.data_length ;
  9563.           if len > 0 
  9564.           and then orig_text.data( len ) /= a_space
  9565.           and then orig_text.data( len ) /= a_hyphen then
  9566.             -- must add space to end
  9567.             len := len + 1 ;
  9568.             orig_text.data_length := len ;
  9569.             orig_text.data( len ) := a_space ;
  9570.           end if ;
  9571.           return true ;
  9572.         end if ;
  9573.       end load_current_text ;
  9574.         
  9575.       procedure margin_initialize is
  9576.       begin -- margin_initialize 
  9577.         -- here ready and willing to work...
  9578.         need_prompt := true ; -- When we leave, we will have to re-prompt
  9579.         -- remember the cursor position 
  9580.         master_buffer.fixed_cursor := start_position ;
  9581.         if do_whole_paragraph then
  9582.           set_repeat_prompt( false , 0 ) ; -- Turn off the counters... 
  9583.           prompt( margin_command_prompt ) ;
  9584.           -- must move backwards to start of current paragraph
  9585.           loop
  9586.           exit when 
  9587.                  not load_current_text(master_buffer.fixed_cursor.line_start);
  9588.             if( text_leng = 0 )
  9589.             or else ( orig_text.data(text_first) = a_break_char ) then
  9590.               if not cursor_forward_line then
  9591.                 null ;
  9592.               end if ;
  9593.           exit ;
  9594.             end if ;
  9595.           exit when not cursor_backward_line ;
  9596.           end loop ;
  9597.           -- ok, we are at the start of a paragraph here....
  9598.         end if ;
  9599.       end margin_initialize ;
  9600.        
  9601.       procedure eat_this_line is
  9602.         -- eat the first line in the open buffer ...
  9603.         -- we know that the entire line exists...
  9604.         starting_pos    : type_buffer_position ;
  9605.         ending_position : type_buffer_position ;
  9606.       begin -- eat_this_line
  9607.         starting_pos := master_buffer.last_open_position + 1 ;
  9608.         if master_buffer.e_buf(starting_pos).data /= buffer_boundry then
  9609.           ending_position := starting_pos + line_length( master_buffer , 
  9610.                                                          starting_pos  ) + 3 ;
  9611.           master_buffer.last_open_position := ending_position - 1 ;
  9612.         end if;
  9613.       end eat_this_line ;
  9614.        
  9615.       procedure read_next_line ( successfull : out boolean ) is
  9616.         -- read in the next input line and eat from buffer ...
  9617.         success : boolean ;
  9618.       begin -- read_next_line 
  9619.         -- first, make sure we have one line at least in the right part of
  9620.         -- the buffer ....
  9621.         if master_buffer.last_open_position + max_bytes_in_line 
  9622.                                             + max_bytes_in_line 
  9623.              > master_buffer.bufcount then
  9624.           -- we must prepare to push/pop...
  9625.           master_buffer.fixed_cursor.line_start 
  9626.             := master_buffer.first_open_position ;
  9627.           close_buffer( master_buffer ) ;
  9628.           -- if we are this close to the end...then we must need to pop from
  9629.           -- bottom...
  9630.           pop_data( master_buffer , thebot , success ) ; 
  9631.           if not success then
  9632.             error( "Disk Error While Re-Filling Paragraph",
  9633.                    not_fatal_error , operator_wait , short_beep ) ;
  9634.             successfull := false ;
  9635.             return ;
  9636.           end if ;
  9637.           open_buffer ( master_buffer , master_buffer.fixed_cursor.line_start ,
  9638.                                         max_bytes_in_line + max_bytes_in_line );
  9639.         end if ;
  9640.         input_line_number := input_line_number + 1 ;
  9641.         if load_current_text( master_buffer.last_open_position + 1 )
  9642.         and then ( text_leng > 0 )
  9643.         and then ( orig_text.data(text_first) /= a_break_char ) then
  9644.           eat_this_line ;
  9645.           successfull := true ;
  9646.         else
  9647.           successfull := false ;
  9648.         end if ;
  9649.       end read_next_line ;
  9650.        
  9651.       procedure merge_this_line ( out_line : in out type_text_line ;
  9652.                                   last_line_of_paragraph : boolean := false ) is
  9653.         -- move the output line over to the buffer .... make sure that
  9654.         -- we have room for two lines in area there..... when done....
  9655.         -- else we will push a block....
  9656.         leading    : type_leading_spaces ;
  9657.         text_first ,
  9658.         text_last  : type_text_length    ;
  9659.         text_leng  : type_line_length    ;
  9660.         ln_start   : type_buffer_position ;
  9661.         new_nxt_line : type_buffer_position ;
  9662.         successfull  : boolean ;
  9663.       begin -- merge_this_line 
  9664.         -- we are working out_line.data ( 1 .. out_line.data_length ) 
  9665.         -- check for justify....
  9666.         get_leading ( out_line , leading, text_first, text_last, text_leng ) ;
  9667.         if text_leng = 0 then
  9668.           return ; -- do nothing (happens possibly at end of paragraph)
  9669.         end if ;
  9670.         if master_buffer.pagezero.justify 
  9671.         and then not last_line_of_paragraph then
  9672.           -- must justify first
  9673.           -- first, must find left boundry
  9674.           do_justify ( out_line ) ;
  9675.           get_leading ( out_line , leading, text_first, text_last, text_leng ) ;
  9676.         end if ;
  9677.         ln_start := master_buffer.first_open_position ;
  9678.         if master_buffer.first_open_position + max_bytes_in_line 
  9679.              >= master_buffer.last_open_position then
  9680.           -- we must push one block...
  9681.           master_buffer.fixed_cursor.line_start := ln_start ;
  9682.           if ln_start > block_size then
  9683.             push_data( master_buffer , thetop , successfull ) ;
  9684.           else
  9685.             push_data( master_buffer , thebot , successfull ) ;
  9686.           end if ;
  9687.           if not successfull then
  9688.             error( "No Disk Space while Re-Filling.",
  9689.                    not_fatal_error , operator_wait , short_beep ) ;
  9690.             return ; -- unable to update ...
  9691.           else
  9692.             ln_start := master_buffer.fixed_cursor.line_start ;
  9693.           end if ;
  9694.         end if ;
  9695.         new_nxt_line := ln_start + text_leng + 3 ;
  9696.         master_buffer.e_buf(ln_start).data    
  9697.                                 := extended_character(text_leng) ;
  9698.         master_buffer.e_buf(ln_start+1 ).data 
  9699.                                 := extended_character(leading) ;
  9700.         for place in 1 .. text_leng loop
  9701.           master_buffer.e_buf(ln_start + 1 + place ).data :=
  9702.                         out_line.data(text_first+place-1) ;
  9703.         end loop ;
  9704.         master_buffer.e_buf(ln_start + text_leng + 2 ).data 
  9705.                                 := extended_character(text_leng) ;
  9706.         for place in ln_start .. ln_start + text_leng + 2 loop
  9707.           master_buffer.e_buf(place).attr := no_screen_attribute ;
  9708.         end loop ;
  9709.         master_buffer.first_open_position := new_nxt_line ;
  9710.         master_buffer.fixed_cursor.line_start := new_nxt_line ;
  9711.         output_line_number := output_line_number + 1 ;
  9712.       end merge_this_line ;
  9713.        
  9714.       procedure add_blank_at_end is
  9715.         first_pos : type_buffer_position ;
  9716.       begin 
  9717.         first_pos := master_buffer.fixed_cursor.line_start ;
  9718.         for posn in first_pos .. first_pos + 2 loop
  9719.           master_buffer.e_buf(posn) := ( extended_character(0) ,
  9720.                                          no_screen_attribute ) ;
  9721.         end loop ;
  9722.         master_buffer.e_buf( first_pos + 3 ) := ( buffer_boundry ,
  9723.                                                   no_screen_attribute ) ;
  9724.         master_buffer.bufcount := first_pos + 3 ;
  9725.       end ;
  9726.        
  9727.       procedure margin_this_paragraph is
  9728.         -- we get here with the current line loaded....
  9729.         out_line   : type_text_line ;
  9730.         blanks     : type_leading_spaces ;
  9731.         in_next_pos  : type_text_length ;
  9732.         out_next_pos : type_text_length ;
  9733.         successfull  : boolean          ;
  9734.         word_start   : type_text_length ;
  9735.         word_stop    : type_text_length ;
  9736.         spaces_stop  : type_text_length ;
  9737.         word_length  : integer          ;
  9738.         lastc        : character        ;
  9739.       begin -- margin_this_paragraph
  9740.         -- try to remember the column to return to...
  9741.         if do_whole_paragraph then
  9742.           cursor_col := max_column_number ;
  9743.         else
  9744.           -- we must remember where the cursor is ... 
  9745.           cursor_col := master_buffer.fixed_cursor.column_offset ;
  9746.         end if ;
  9747.         -- prepare to open the buffer....
  9748.         input_line_number := master_buffer.fixed_cursor.file_line_number ;
  9749.         output_line_number := input_line_number ;
  9750.         open_buffer( master_buffer , master_buffer.fixed_cursor.line_start ,
  9751.                                      max_bytes_in_line + max_bytes_in_line ) ;
  9752.         eat_this_line ;
  9753.         -- ok, here with a line in memory, and buffer open...
  9754.         if do_whole_paragraph then
  9755.           -- we start with para margin blanks...
  9756.           blanks := master_buffer.pagezero.paramargin ;
  9757.         else
  9758.           blanks := leading ; -- keep leading spaces intact...
  9759.         end if ;
  9760.         for pos in 1 .. blanks loop
  9761.           out_line.data(pos) := a_space ;
  9762.         end loop ;
  9763.         out_line.data_length := blanks ;
  9764.         in_next_pos  := text_first ;
  9765.         out_next_pos := blanks + 1 ;
  9766.         successfull  := true       ;
  9767.         loop
  9768.           -- now, loop, moving over text from input to output ...
  9769.           -- work orig_text to text_last ...
  9770.           if in_next_pos > text_last then
  9771.             read_next_line ( successfull ) ;
  9772.             in_next_pos := text_first ;
  9773.         exit when not successfull ;
  9774.           else
  9775.             -- get the next word from input, move to output if room ...
  9776.             word_start := in_next_pos ;
  9777.             loop
  9778.               in_next_pos := in_next_pos + 1 ;
  9779.             exit when ( in_next_pos > orig_text.data_length )
  9780.                  or else ( orig_text.data( in_next_pos ) = a_space )
  9781.                  or else ( orig_text.data( in_next_pos ) = a_hyphen ) ;
  9782.             end loop ;
  9783.             if in_next_pos > orig_text.data_length then
  9784.               word_stop := in_next_pos - 1 ;
  9785.               spaces_stop := word_stop ;
  9786.             elsif orig_text.data( in_next_pos ) = a_hyphen then
  9787.               word_stop := in_next_pos ;
  9788.               if in_next_pos < orig_text.data_length 
  9789.               and then orig_text.data( in_next_pos + 1 ) = a_space then
  9790.                 spaces_stop := spaces_stop + 1 ;
  9791.               else
  9792.                 spaces_stop := word_stop ;
  9793.               end if ;
  9794.               -- now, kill all spaces following...
  9795.               in_next_pos := spaces_stop ;
  9796.               loop
  9797.                 in_next_pos := in_next_pos + 1 ;
  9798.               exit when ( in_next_pos > orig_text.data_length )
  9799.                    or else ( orig_text.data( in_next_pos ) /= a_space ) ;
  9800.               end loop ;
  9801.             else
  9802.               -- here on a single space...
  9803.               word_stop := in_next_pos - 1 ;
  9804.               -- we allow a second space in some instances......
  9805.               lastc := character'val( orig_text.data(word_stop) ) ;
  9806.               if in_next_pos < orig_text.data_length -- more text exists
  9807.               and then orig_text.data( in_next_pos + 1 ) = a_space 
  9808.               and then (    ( lastc = '.' ) 
  9809.                          or ( lastc = '!' )
  9810.                          or ( lastc = '"' )
  9811.                          or ( lastc = ')' )
  9812.                          or ( lastc = '?' )
  9813.                          or ( lastc = ',' ) 
  9814.                          or ( lastc = ']' )
  9815.                          or ( lastc = ':' ) ) then
  9816.                 spaces_stop := in_next_pos + 1 ;
  9817.                 in_next_pos := in_next_pos + 1 ;
  9818.               else
  9819.                 spaces_stop := in_next_pos ; -- only allow one space..
  9820.               end if ;
  9821.               loop
  9822.                 in_next_pos := in_next_pos + 1 ;
  9823.               exit when ( in_next_pos > orig_text.data_length )
  9824.                    or else ( orig_text.data( in_next_pos ) /= a_space ) ;
  9825.               end loop ;
  9826.               -- spaces_stop := in_next_pos - 1 ; -- if we allow any number
  9827.               -- of spaces, then the above line would go in instead....
  9828.             end if ;
  9829.             -- ok, we are here with word_start , word_stop and spaces_stop
  9830.             word_length := word_stop - word_start + 1 ;
  9831.             if out_next_pos + word_length - 1 
  9832.              > master_buffer.pagezero.rmargin then
  9833.               -- it cannot fit on this line.....
  9834.               out_line.data_length := out_next_pos - 1 ;
  9835.               merge_this_line ( out_line ) ;
  9836.               blanks := master_buffer.pagezero.lmargin ;
  9837.               for pos in 1 .. blanks loop
  9838.                 out_line.data(pos) := a_space ;
  9839.               end loop ;
  9840.               out_line.data_length := blanks ;
  9841.               out_next_pos := blanks + 1 ;
  9842.             end if ;
  9843.             for pos in 1 .. word_length loop
  9844.               out_line.data ( out_next_pos )
  9845.                           := orig_text.data ( word_start + pos - 1 ) ;
  9846.               out_next_pos := out_next_pos + 1 ;
  9847.             end loop ;
  9848.             for pos in word_stop + 1 .. spaces_stop loop
  9849.               out_line.data(out_next_pos) := a_space ;
  9850.               out_next_pos := out_next_pos + 1 ;
  9851.             end loop ;
  9852.           end if ;
  9853.         end loop ;
  9854.         -- and move last output line over to input...
  9855.         out_line.data_length := out_next_pos - 1 ;
  9856.         merge_this_line ( out_line , true ) ;
  9857.         close_buffer ( master_buffer ) ;
  9858.         -- reposition cursor-- we know that orig_cursor_location is set as the line/column we
  9859.         -- had upon entry...
  9860.         master_buffer.fixed_cursor.buffer_position := 0 ;
  9861.         master_buffer.fixed_cursor.file_line_number:= output_line_number ;
  9862.         master_buffer.fixed_cursor.column_offset := 0 ;
  9863.         -- master_buffer.fixed_cursor.line_start already set...
  9864.         if master_buffer.e_buf( master_buffer.fixed_cursor.line_start ).data
  9865.                       = buffer_boundry 
  9866.         -- we might have to fix up end of file...
  9867.         and then output_line_number > 1 
  9868.         -- not on first line...
  9869.         and then master_buffer.e_buf(master_buffer.fixed_cursor.line_start)
  9870.                         .data /= 0 then
  9871.           -- must add in three nulls....
  9872.           add_blank_at_end;
  9873.         end if ;
  9874.         -- Note that if we really wanted to make markers work after
  9875.         -- margining, here is where we would implement it...
  9876.         if do_whole_paragraph then
  9877.           jump_to_position ( master_buffer ,
  9878.                              master_buffer.fixed_cursor.file_line_number ,
  9879.                              master_buffer.fixed_cursor.column_offset ,
  9880.                              false ) ;
  9881.         else
  9882.           jump_to_position ( master_buffer , 
  9883.                              orig_cursor_location.file_line_number ,
  9884.                              orig_cursor_location.column_offset ,
  9885.                              false ) ;
  9886.         end if ;
  9887.       end margin_this_paragraph ;
  9888.        
  9889.       procedure margin_finish is
  9890.       begin -- margin_finish
  9891.         show_screen ( master_buffer ,
  9892.                       master_buffer.fixed_cursor ,
  9893.                       window_height ( master_buffer ) / 2 ) ;
  9894.       end margin_finish ;
  9895.        
  9896.     begin -- do_re_margin_command 
  9897.       if do_whole_paragraph 
  9898.       and then not ( master_buffer.pagezero.filling 
  9899.                and not master_buffer.pagezero.autoindent ) then
  9900.         -- must check information on status...
  9901.         -- inappropriate environment
  9902.         error( "Inappropriate Environment.",
  9903.                not_fatal_error , operator_wait , short_beep ) ;
  9904.         return ;
  9905.       end if ;
  9906.       -- start of margining....
  9907.       margin_initialize ;
  9908.       while paragraphs_remaining > 0 loop
  9909.         paragraphs_remaining := paragraphs_remaining - 1 ;
  9910.         if do_whole_paragraph then
  9911.           -- first, skip any leading lines which are commands 
  9912.           -- or blank lines
  9913.           loop
  9914.           exit when 
  9915.             not load_current_text ( master_buffer.fixed_cursor.line_start ) 
  9916.             or else ( text_leng = 0 )
  9917.             or else ( orig_text.data(text_first) /= a_break_char ) ;
  9918.             if not cursor_forward_line then
  9919.               raise end_of_file ;
  9920.             end if ;
  9921.           end loop ;
  9922.         else
  9923.           if not load_current_text ( master_buffer.fixed_cursor.line_start) then
  9924.             raise called_on_command_line ;
  9925.           end if ;
  9926.           if ( text_leng = 0 )
  9927.           or else ( orig_text.data(text_first) = a_break_char ) then 
  9928.             raise called_on_command_line ; 
  9929.           end if ;
  9930.         end if ;
  9931.         -- we get here with the current line loaded, and ready to go....
  9932.         margin_this_paragraph ;
  9933.       end loop ;
  9934.       margin_finish ;
  9935.     exception
  9936.       when end_of_file            => margin_finish ;
  9937.       when called_on_command_line => margin_finish ;
  9938.     end do_re_margin_command ;
  9939.       
  9940.     procedure do_enter_exchange_mode is
  9941.       -- where is the exchange cursor in the file ? 
  9942.       x_line_number   : line_number   ;
  9943.       x_column_number : column_position ;
  9944.       -- where is the exchange cursor on the screen ?
  9945.       w_line_number   : window_line_number ;
  9946.       -- what does the screen look like ? 
  9947.       w_top_line      : line_number        ;
  9948.       w_bot_line      : line_number        ;
  9949.       w_left_column   : column_position    ;
  9950.       w_right_column  : column_position    ;
  9951.       -- what is the home position for exchange with a <cr> ?
  9952.       home_column     : column_position := 0 ;
  9953.       -- what is the text for the current line ? 
  9954.       we_have_current_text : boolean := false ;
  9955.       txt             : type_text_line ;
  9956.       orig_text       : type_text_line ; -- the original text line....
  9957.       command_char    : character      ;
  9958.       editor_command  : editor_globals.an_editor_command ;
  9959.       save_cursor     : cursor_position ;
  9960.         
  9961.       procedure set_window_positions is
  9962.         -- we need to set the values that tell us were the window is
  9963.       begin
  9964.         w_top_line      := master_buffer.top_screen_cursor.file_line_number ;
  9965.         w_bot_line      := w_top_line + window_height( master_buffer ) - 1  ;
  9966.         w_left_column   := lowest_column_number( master_buffer ) ;
  9967.         w_right_column  := highest_column_number( master_buffer ) ;
  9968.       end;
  9969.         
  9970.       procedure initialize_exchange is
  9971.       begin -- initialize_exchange 
  9972.         set_window_positions ;
  9973.         -- where is the exchange cursor in the file ? 
  9974.         x_line_number   := master_buffer.fixed_cursor.file_line_number ;
  9975.         x_column_number := master_buffer.fixed_cursor.column_offset    ;
  9976.         -- where is the exchange cursor on the screen ?
  9977.         w_line_number   := x_line_number - w_top_line + 1 ;
  9978.         set_repeat_prompt( false , 0 ) ;
  9979.         prompt( exchange_command_prompt ) ;
  9980.         show_cursor( master_buffer ) ;
  9981.         save_cursor := master_buffer.fixed_cursor ;
  9982.       end initialize_exchange ;
  9983.         
  9984.       procedure get_c_or_command( c  : out character                        ;
  9985.                                   cmd: out editor_globals.an_editor_command ) is
  9986.         -- get either a printable character or else get an editor command...
  9987.         -- note that here, printable characters take priority over commands
  9988.         physical_c : character ;
  9989.         physical_command : crt.special_keys ;
  9990.       begin -- get_c_or_command
  9991.         crt_windows.key_input( physical_c , physical_command ) ;
  9992.         if physical_command = key_character 
  9993.         and then physical_c in ' ' .. '~' then
  9994.           -- easy... is just a printable character ...????
  9995.           c := physical_c ;
  9996.           cmd := editor_customization.illegal_command ;
  9997.           -- I really wanted to use editor_globals.illegal_command.......
  9998.         else
  9999.           -- need to find out what it might be...
  10000.           translate( physical_c , physical_command , c , cmd ) ;
  10001.         end if ;
  10002.       end get_c_or_command ;
  10003.         
  10004.       procedure reshow_line is
  10005.         -- for a reject command 
  10006.       begin -- reshow_line ;
  10007.         clear_end_of_line ( master_buffer , w_line_number , w_left_column ) ;
  10008.         show_line ( master_buffer ,
  10009.                     master_buffer.fixed_cursor.line_start ,
  10010.                     master_buffer.fixed_cursor.file_line_number ) ; 
  10011.         show_cursor( master_buffer ) ;
  10012.       end reshow_line ;
  10013.       
  10014.       procedure load_current_text is
  10015.       begin -- load_current_text
  10016.         save_cursor := master_buffer.fixed_cursor ;
  10017.         get_text_line( master_buffer , save_cursor.line_start , orig_text ) ;
  10018.         for posn in orig_text.data_length + 1 .. max_column_number loop
  10019.           orig_text.data(posn) := extended_character(32); -- spaces...
  10020.         end loop ;
  10021.         txt := orig_text ;
  10022.         we_have_current_text := true ;
  10023.       end load_current_text ;
  10024.         
  10025.       procedure replace_current_text is
  10026.         leading    : type_leading_spaces ;
  10027.         text_first ,
  10028.         text_last  : type_text_length    ;
  10029.         text_leng  : type_line_length    ;
  10030.         old_leng   : type_line_length ;
  10031.         ln_start   : type_buffer_position ;
  10032.         old_nxt_line ,
  10033.         new_nxt_line : type_buffer_position ;
  10034.         successfull  : boolean ;
  10035.       begin -- replace_current_text 
  10036.         -- first, we need to check out this line.... 
  10037.         -- has it changed????
  10038.         if txt /= orig_text then
  10039.           -- yes it has changed....
  10040.           -- Then, reset the length and the leading spaces ...
  10041.           -- x_column_number - 1 is the highest column number worked with... 
  10042.           if x_column_number - 1 > txt.data_length then
  10043.             txt.data_length := x_column_number - 1 ;
  10044.           end if ;
  10045.           get_leading ( txt , leading , text_first , text_last , text_leng ) ;
  10046.           ln_start := master_buffer.fixed_cursor.line_start ;
  10047.           old_leng   := line_length( master_buffer , ln_start ) ;
  10048.           -- move this line into the buffer....
  10049.           -- 1: Open or close Buffer by appropriate positions
  10050.           -- At most, we will add text_leng characters, because the line
  10051.           -- must already have the 3 control characters
  10052.           if old_leng < text_leng then
  10053.             -- must make sure we have room in buffer...
  10054.             if master_buffer.bufcount - old_leng + text_leng > max_buffer_size
  10055.                        then
  10056.               -- we must push one block...
  10057.               if ln_start > block_size then
  10058.                 push_data( master_buffer , thetop , successfull ) ;
  10059.               else
  10060.                 push_data( master_buffer , thebot , successfull ) ;
  10061.               end if ;
  10062.               if not successfull then
  10063.                 error( "Unable to update line. No Temporary File Room.",
  10064.                        not_fatal_error , operator_wait , short_beep ) ;
  10065.                 return ; -- unable to update ...
  10066.               else
  10067.                 ln_start := master_buffer.fixed_cursor.line_start ;
  10068.               end if ;
  10069.             end if ;
  10070.           end if ;
  10071.           old_nxt_line := ln_start +  old_leng + 3 ;
  10072.           new_nxt_line := ln_start + text_leng + 3 ;
  10073.           shift_buffer_area ( master_buffer , old_nxt_line , new_nxt_line , 
  10074.                               master_buffer.bufcount - old_nxt_line + 1 ) ;
  10075.           master_buffer.bufcount:=master_buffer.bufcount -old_leng +text_leng ;
  10076.           -- that shortens or lengthens as appropriate...
  10077.           --              3: Add the new line
  10078.           master_buffer.e_buf(ln_start).data    
  10079.                                   := extended_character(text_leng) ;
  10080.           master_buffer.e_buf(ln_start+1 ).data 
  10081.                                   := extended_character(leading) ;
  10082.           for place in 1 .. text_leng loop
  10083.             master_buffer.e_buf(ln_start + 1 + place ).data :=
  10084.                           txt.data(text_first+place-1) ;
  10085.           end loop ;
  10086.           master_buffer.e_buf(ln_start + text_leng + 2 ).data 
  10087.                                   := extended_character(text_leng) ;
  10088.           for place in ln_start .. ln_start + text_leng + 2 loop
  10089.             master_buffer.e_buf(place).attr := no_screen_attribute ;
  10090.           end loop ;
  10091.           --              4: Adjust Markers
  10092.           -- any changes in the current line do not affect other lines, and
  10093.           -- the typeover on the current line makes it impossible to figure
  10094.           -- any better setting than the current one...
  10095.         end if ;
  10096.         we_have_current_text := false ;
  10097.       end replace_current_text ;
  10098.         
  10099.       procedure make_next_position_valid_on_screen is
  10100.       begin
  10101.         if x_column_number = w_right_column then
  10102.           -- we are going off the screen ...
  10103.           master_buffer.fixed_cursor.column_offset := x_column_number + 1 ;
  10104.           show_cursor( master_buffer ) ;
  10105.           set_window_positions ;
  10106.           goto_line_column( master_buffer , w_line_number , w_left_column ) ;
  10107.           for posn in w_left_column .. x_column_number - 1 loop
  10108.             -- put out the new line ...
  10109.             put( txt.data(posn) ) ;
  10110.           end loop ;
  10111.         end if ;
  10112.       end;
  10113.         
  10114.       procedure do_char ( c : in character ) is 
  10115.       begin -- do_char
  10116.         if x_column_number <= max_column_number then
  10117.           -- first, check screen ...
  10118.           make_next_position_valid_on_screen ;
  10119.           -- then, change screen
  10120.           put( c ) ;
  10121.           -- next, change txt 
  10122.           txt.data( x_column_number ) := extended_character( character'pos(c) );
  10123.           -- finally, change position 
  10124.           x_column_number := x_column_number + 1 ;
  10125.         end if ;
  10126.       end do_char ;
  10127.         
  10128.       procedure backup_char is
  10129.       begin -- backup_char
  10130.         if x_column_number > 1 then
  10131.           if x_column_number = w_left_column then 
  10132.             -- we are going off the screen ...
  10133.             master_buffer.fixed_cursor.column_offset := x_column_number - 1 ;
  10134.             show_cursor( master_buffer ) ;
  10135.             set_window_positions ;
  10136.             goto_line_column( master_buffer , w_line_number , w_left_column ) ;
  10137.             for posn in w_left_column .. x_column_number - 1 loop
  10138.               -- put out the new line ...
  10139.               put( txt.data(posn) ) ;
  10140.             end loop ;
  10141.           end if ;
  10142.           x_column_number := x_column_number - 1 ;
  10143.           goto_line_column( master_buffer , w_line_number , x_column_number ) ;
  10144.           txt.data( x_column_number ) := orig_text.data( x_column_number ) ;
  10145.           put( txt.data( x_column_number ) ) ;
  10146.           goto_line_column( master_buffer , w_line_number , x_column_number ) ;
  10147.         end if ;
  10148.       end backup_char ;
  10149.         
  10150.       procedure forward_char is
  10151.       begin -- forward_char 
  10152.         if x_column_number <= max_column_number then
  10153.           -- first, check screen ...
  10154.           make_next_position_valid_on_screen ;
  10155.           -- then, change screen
  10156.           put( txt.data( x_column_number ) ) ;
  10157.           -- finally, change position 
  10158.           x_column_number := x_column_number + 1 ;
  10159.         end if ;
  10160.       end forward_char ;
  10161.         
  10162.       procedure move_up ( new_column_number : column_position ) is
  10163.         -- a zero means first text on line 
  10164.       begin -- move_up 
  10165.         if cursor_backward_line then
  10166.           -- ok, we moved back a line...
  10167.           -- set the column number ;
  10168.           if new_column_number > 0 then
  10169.             master_buffer.fixed_cursor.column_offset := new_column_number ;
  10170.           else
  10171.             master_buffer.fixed_cursor.column_offset :=
  10172.               num_leading_spaces( master_buffer , 
  10173.                                   master_buffer.fixed_cursor.line_start ) + 1 ;
  10174.           end if ;
  10175.           x_column_number := master_buffer.fixed_cursor.column_offset ;
  10176.           if x_line_number = w_top_line then
  10177.             -- we must reshow screen ...
  10178.             show_cursor( master_buffer ) ;
  10179.             save_cursor := master_buffer.fixed_cursor ;
  10180.             set_window_positions ;
  10181.             x_line_number   := x_line_number - 1 ;
  10182.             w_line_number   := x_line_number - w_top_line + 1 ;
  10183.           else
  10184.             show_cursor( master_buffer ) ;
  10185.             x_line_number   := x_line_number - 1 ;
  10186.             w_line_number   := w_line_number - 1 ;
  10187.           end if ;
  10188.         end if ;
  10189.       end move_up ;
  10190.         
  10191.       procedure move_down ( new_column_number : column_position ) is
  10192.         -- a zero means first text on line 
  10193.       begin -- move_down 
  10194.         if cursor_forward_line then
  10195.           -- ok, we moved back a line...
  10196.           -- set the column number ;
  10197.           if new_column_number > 0 then
  10198.             master_buffer.fixed_cursor.column_offset := new_column_number ;
  10199.           else
  10200.             master_buffer.fixed_cursor.column_offset :=
  10201.               num_leading_spaces( master_buffer , 
  10202.                                   master_buffer.fixed_cursor.line_start ) + 1 ;
  10203.           end if ;
  10204.           x_column_number := master_buffer.fixed_cursor.column_offset ;
  10205.           if x_line_number = w_bot_line then
  10206.             -- we must reshow screen ...
  10207.             show_cursor( master_buffer ) ;
  10208.             save_cursor := master_buffer.fixed_cursor ;
  10209.             set_window_positions ;
  10210.             x_line_number   := x_line_number + 1 ;
  10211.             w_line_number   := x_line_number - w_top_line + 1 ;
  10212.           else
  10213.             show_cursor( master_buffer ) ;
  10214.             x_line_number   := x_line_number + 1 ;
  10215.             w_line_number   := w_line_number + 1 ;
  10216.           end if ;
  10217.         end if ;
  10218.       end move_down ;
  10219.           
  10220.       procedure set_home_column is
  10221.       begin -- set_home_column
  10222.         clear_prompt_end_of_line( master_buffer , 1 , 1 ) ;
  10223.         goto_prompt_line_column( master_buffer , 1 , 1 ) ;
  10224.         put(">eXchange: Home column ");
  10225.         if home_column = 0 then
  10226.           -- they are setting the column
  10227.           home_column := x_column_number ;
  10228.           put("set to column #");
  10229.           put( home_column , 1 ) ;
  10230.         else
  10231.           -- resetting the column 
  10232.           home_column := 0 ;
  10233.           put("erased ");
  10234.         end if ;
  10235.         goto_line_column( master_buffer , w_line_number , x_column_number ) ;
  10236.       end set_home_column ;
  10237.         
  10238.       procedure finish_exchange is
  10239.       begin -- finish_exchange 
  10240.         need_prompt := true ;
  10241.         master_buffer.fixed_cursor.file_line_number := x_line_number   ;
  10242.         master_buffer.fixed_cursor.column_offset    := x_column_number ;
  10243.       end finish_exchange ;
  10244.         
  10245.     begin -- do_enter_exchange_mode 
  10246.       initialize_exchange ;
  10247.       loop
  10248.         get_c_or_command( command_char , editor_command ) ;
  10249.         case editor_command is
  10250.           when illegal_command => -- is a character to put into line 
  10251.                                   if command_char /= ascii.nul then
  10252.                                     -- is a real character...
  10253.                                     if not we_have_current_text then
  10254.                                       load_current_text ;
  10255.                                     end if ;
  10256.                                     -- Now, put the character in...
  10257.                                     -- and then move right...
  10258.                                     do_char( command_char ) ;
  10259.                                   end if ;
  10260.           when up_command      => -- finish current line and move up
  10261.                                   if we_have_current_text then
  10262.                                     replace_current_text ;
  10263.                                   end if ;
  10264.                                   move_up( x_column_number ) ;
  10265.           when down_command    => -- finish current line and move down
  10266.                                   if we_have_current_text then
  10267.                                     replace_current_text ;
  10268.                                   end if ;
  10269.                                   move_down( x_column_number ) ;
  10270.           when left_command    => -- replace character & move left 
  10271.                                   if not we_have_current_text then
  10272.                                     load_current_text ;
  10273.                                   end if ;
  10274.                                   backup_char ;
  10275.           when right_command   => -- skip one character to the right 
  10276.                                   if not we_have_current_text then
  10277.                                     load_current_text ;
  10278.                                   end if ;
  10279.                                   forward_char ;
  10280.           when accept_command  => -- move the text line back into buffer
  10281.                                   if we_have_current_text then
  10282.                                     replace_current_text ;
  10283.                                   end if ;
  10284.           when reject_command  => -- redraw the line as it was...
  10285.                                   if we_have_current_text then
  10286.                                     -- have to fix it...
  10287.                                     reshow_line ;
  10288.                                   end if ;
  10289.           when advance_line_command 
  10290.              | forward_line_command => -- move to next line at home position 
  10291.                                   if we_have_current_text then
  10292.                                     replace_current_text ;
  10293.                                   end if ;
  10294.                                   move_down( home_column ) ;
  10295.           when home_command    => -- adjust the home position 
  10296.                                   set_home_column ;
  10297.           when others          => null ; -- skip them......
  10298.         end case ;
  10299.       exit when editor_command = accept_command 
  10300.              or editor_command = reject_command ;
  10301.       end loop ;
  10302.       finish_exchange ;
  10303.     end do_enter_exchange_mode ;
  10304.       
  10305.   begin -- editor_even_more_packages
  10306.     -- EDITMAN3 by SAIC/Clearwater More Main Editor Packages   26 Dec 84
  10307.     -- REMARGIN by SAIC/Clearwater Re Margin Package           31 Dec 84
  10308.     -- EXCHANGE by SAIC/Clearwater Exchange Package            22 Feb 85
  10309.     null ;
  10310.   end editor_even_more_packages ;
  10311.      
  10312.   --$$$- EDITMAN3
  10313.  
  10314. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  10315. --editfile
  10316. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  10317.  
  10318. --$$$+ EDITFILE
  10319.    
  10320.   --
  10321.   -- File 018
  10322.   --
  10323.   -- Editor Written By Robert S. Cymbalski
  10324.   --                   Science Applications International Corporation
  10325.   --                   Energy Systems Group
  10326.   --                   Ada Software Development Project Team
  10327.   --                   2280 U.S. Highway 19 North, Suite 120
  10328.   --                   Clearwater, Florida  33575
  10329.   -- 
  10330.   --
  10331.   -- Editor Revised from text Copyright (c) 1984 , R.S.Cymbalski
  10332.   -- 
  10333.    
  10334.   with text_io ;
  10335.    
  10336.   with string_library  ;
  10337.   use  string_library  ;
  10338.    
  10339.   with basic_io_system ;
  10340.    
  10341.   with crt_customization ;
  10342.   use  crt_customization ;
  10343.   use  crt               ;
  10344.   use  editor_customization ;
  10345.    
  10346.   with crt_windows     ;
  10347.    
  10348.   with Wordp_Globals   ;
  10349.   use  Wordp_Globals   ;
  10350.  
  10351.   with editor_globals     ;
  10352.   use  editor_globals     ;
  10353.    
  10354.   with edit_windows       ;
  10355.   use  edit_windows       ;
  10356.    
  10357.   with buffer_package  ;
  10358.   use  buffer_package  ;
  10359.   use  buffer_block_io ;
  10360.   use  buffer_general  ;
  10361.   use  buffer_lines    ;
  10362.    
  10363.   with markers            ;
  10364.    
  10365.   with editor_misc        ;
  10366.   use  editor_misc        ;
  10367.   use  copy_package ;
  10368.    
  10369.   with environment_input_output ;
  10370.    
  10371.   package editor_files is
  10372.    
  10373.     procedure editor_master_reset ;
  10374.       -- initialize the editor
  10375.        
  10376.     procedure editor_re_initialize ( Had_Old_File : out Boolean ) ;
  10377.         -- Returns true if the buffer was loaded from a text file  
  10378.     
  10379.     procedure do_copy_command ;
  10380.      
  10381.     procedure do_quit_command ( partial , total : in out boolean ) ;
  10382.      
  10383.   end editor_files ;
  10384.    
  10385.   package body editor_files is
  10386.    
  10387.     procedure editor_master_reset is
  10388.       -- initialize the editor
  10389.     begin -- editor_master_reset
  10390.       -- text_io.put(" Init Buffer ");
  10391.       initialize_buffer( master_buffer , 1 ) ;
  10392.       -- Initialize a buffer as buffer #1
  10393.       -- text_io.put(" I B End ");
  10394.       master_window := crt_windows.create_window ( 
  10395.                                             1 , basic_io_system.total_crt_col ,
  10396.                                             1 , basic_io_system.total_crt_line ,
  10397.                                             true , 1 ) ;
  10398.       -- text_io.put(" Create Window End ");
  10399.       -- Create a screen window
  10400.       -- Make the window the entire screen, with a 1 line status area
  10401.       -- at the top of the window
  10402.       map_window( master_window , master_buffer ) ;
  10403.       -- Map the master buffer onto the master_window
  10404.       clear_prompt( master_buffer ) ;
  10405.       clear_window( master_buffer ) ;
  10406.     end editor_master_reset ;
  10407.        
  10408.     procedure editor_re_initialize ( Had_Old_File : out Boolean ) is
  10409.         -- Returns true if the buffer was loaded from a text file  
  10410.       final_name : ascii_text_file_name ;
  10411.       ok : boolean ;
  10412.       working_had_old_file : boolean ;
  10413.     begin -- editor_re_initialize
  10414.       need_prompt := true  ; 
  10415.       clear_prompt( master_buffer ) ;
  10416.       clear_window( master_buffer ) ;
  10417.       if editor_entry_input_file_name = blank_file_name then 
  10418.         ok := false ;
  10419.       else
  10420.         ok_to_read( editor_entry_input_file_name , final_name , ok ) ;
  10421.       end if ;
  10422.       if not ok then
  10423.         -- we need to read in another file name 
  10424.         -- here on no input file name or file does not exist.
  10425.         if editor_entry_input_file_name /= blank_file_name then
  10426.           error( " File """ & string_library.compress(final_name)
  10427.                                           & """ does not exist." ,
  10428.                  not_fatal_error , operator_wait , short_beep ) ;
  10429.         end if ;
  10430.         loop
  10431.           set_prompt( master_buffer , 1 , 
  10432.                       editor_customization.enter_input_file_name_prompt ) ;
  10433.           editor_requested_input_file_name := get_input_filename_or_return ;
  10434.           if editor_requested_input_file_name = blank_file_name then
  10435.             -- we have to make a new file
  10436.             working_had_old_file := false ; -- No old file to load, just need to insert
  10437.           else
  10438.             if editor_requested_input_file_name( 1 ) = ascii.esc then
  10439.               -- an error, the file name did not exist
  10440.               error(" File """ & compress(editor_requested_input_file_name
  10441.                        ( 2 .. editor_requested_input_file_name'length ) )
  10442.                                   & """ does not exist." ,
  10443.                      not_fatal_error , operator_wait , short_beep ) ;
  10444.             else
  10445.               working_had_old_file := true ;  -- a good file name and exists....
  10446.             end if ;
  10447.           end if ;
  10448.         exit when editor_requested_input_file_name( 1 ) /= ascii.esc ;
  10449.         end loop ;
  10450.       else
  10451.         -- a good entry file name
  10452.         editor_requested_input_file_name := final_name ;
  10453.         working_had_old_file := true ;
  10454.       end if ;
  10455.       -- here with either an old file or else nothing...
  10456.       if working_had_old_file then
  10457.         load_file( master_buffer , editor_requested_input_file_name ) ;
  10458.         show_screen( master_buffer ) ;
  10459.       else
  10460.         -- need to set the default environment
  10461.         master_buffer.input_file_name := blank_file_name ;
  10462.         re_initialize(master_buffer);  -- reset as empty buffer
  10463.         environment_input_output.users_default_header(master_buffer.pagezero);
  10464.       end if ;
  10465.       had_old_file := working_had_old_file ;
  10466.     end editor_re_initialize ;
  10467.       
  10468.     procedure do_copy_command is
  10469.      
  10470.       function mapup ( s : in pstring ) return pstring is
  10471.         new_s : pstring := s ;
  10472.       begin
  10473.         for posn in 1 .. length(new_s) loop
  10474.           if new_s.data(posn) in 'a' .. 'z' then
  10475.             new_s.data(posn) := character'val( character'pos( new_s.data(posn) )
  10476.                                                - character'pos('a')
  10477.                                                + character'pos('A') );
  10478.           end if ;
  10479.         end loop ;
  10480.         return new_s ;
  10481.       end;
  10482.        
  10483.       procedure copy_in_copy_file is
  10484.         format , 
  10485.         default ,
  10486.         users_response: pstring ;
  10487.         fname : ascii_text_file_name ;
  10488.         blank_marker : constant str10 := "          " ;
  10489.         marker_one : str10 ;
  10490.         marker_two : str10 ;
  10491.         place1 , place2 , place3 : integer ;
  10492.         ret_file_name : ascii_text_file_name := no_file ;
  10493.         pfile_name    : pstring ;
  10494.         ok            : boolean ;
  10495.         temp_marker   : pstring ;
  10496.         orig_line     : line_number ;
  10497.         orig_column   : column_position ;
  10498.         orig_screen_line : window_line_number ;
  10499.       begin -- copy_in_copy_file
  10500.         loop
  10501.           -- while we have erroneous file names returned...
  10502.           -- or else bad marker names....
  10503.           fname      := no_file ;
  10504.           marker_one := blank_marker ;
  10505.           marker_two := blank_marker ;
  10506.           clear_prompt( master_buffer ) ;
  10507.           goto_prompt_line_column( master_buffer , 1 , 1 );
  10508.           put( Enter_Copied_In_File_Name_Prompt );
  10509.           format   := string_to_pstring("                              ");
  10510.           default  := format ;
  10511.           users_response := crt_windows.string_read( format , default ) ;
  10512.         exit when users_response = default ; -- do nothing ...
  10513.           -- First, separate out the part from '[' on...
  10514.           if position('[',users_response) /= 0 then
  10515.             -- they asked for markers work...
  10516.             place1 := position('[',users_response) + 1 ;
  10517.             place2 := position(',',users_response) + 1 ;
  10518.             place3 := position(']',users_response) + 1 ;
  10519.             if place3 = 1 then
  10520.               place3 := length(users_response) + 2 ;
  10521.               if place2 = 1 then
  10522.                 place2 := length(users_response) + 2 ;
  10523.               end if ;
  10524.             end if ;
  10525.             if place2 - place1 > 1 then
  10526.               -- we want to work first marker 
  10527.               for offset in 1 .. place2 - place1 - 1 loop
  10528.                 temp_marker.data(offset)
  10529.                                    := users_response.data( place1 + offset - 1);
  10530.               end loop ;
  10531.               set_length( temp_marker , place2 - place1 - 1 ) ;
  10532.               temp_marker := mapup( compress( temp_marker ) ) ;
  10533.               if length( temp_marker ) > marker_one'last then
  10534.                 set_length( temp_marker , marker_one'last ) ;
  10535.               end if ;
  10536.               for posn in 1 .. length(temp_marker) loop
  10537.                 marker_one(posn) := temp_marker.data(posn) ;
  10538.               end loop ;
  10539.             end if ;
  10540.             if place3 - place2 > 1 then
  10541.               -- we want to work second marker
  10542.               for offset in 1 .. place3 - place2 - 1 loop
  10543.                 temp_marker.data(offset)
  10544.                                    := users_response.data( place2 + offset - 1);
  10545.               end loop ;
  10546.               set_length( temp_marker , place3 - place2 - 1 ) ;
  10547.               temp_marker := mapup( compress( temp_marker ) ) ;
  10548.               if length( temp_marker ) > marker_two'last then
  10549.                 set_length( temp_marker , marker_two'last ) ;
  10550.               end if ;
  10551.               for posn in 1 .. length(temp_marker) loop
  10552.                 marker_two(posn) := temp_marker.data(posn) ;
  10553.               end loop ;
  10554.             end if ;
  10555.             -- now, get rid of the excess characters to check the file name
  10556.             set_length( users_response , place1 - 2 ) ;
  10557.           -- else use blank markers already set...
  10558.           end if ;
  10559.           -- we end up here after cleaning off the marker names ( if any ) 
  10560.           -- Now, we will first allow the addition of .text 
  10561.           if length(users_response) <= maximum_file_name_length - 
  10562.                                  default_text_file_suffix'length then
  10563.             if position('.',users_response) = 0 then
  10564.               users_response := compress(users_response) 
  10565.                                                     & default_text_file_suffix ;
  10566.             end if;
  10567.           end if ;
  10568.           if users_response.data( length(users_response) ) = '.' then
  10569.             set_length( users_response , length(users_response) - 1 ) ;
  10570.             -- eat last '.' 
  10571.           end if ;
  10572.           if length(users_response) > maximum_file_name_length then
  10573.             set_length( users_response , maximum_file_name_length ) ;
  10574.           end if ;
  10575.           fname( 1 .. length(users_response) ) :=
  10576.                           users_response.data( 1 .. length(users_response) ) ;
  10577.           -- Now, check for all valid characters 
  10578.           ok       := true ;
  10579.           for posn in 1 .. maximum_file_name_length loop
  10580.             ok := ok and 
  10581.               (  ( ( fname( posn ) = basic_io_system.directory_separator )
  10582.                and ( fname( posn ) /= ' ' ) )
  10583.               or ( fname( posn ) = '.' ) 
  10584.               or ( ( fname(posn)>='A' ) and ( fname(posn)<='Z' ) )
  10585.               or ( ( fname(posn)>='a' ) and ( fname(posn)<='z' ) )
  10586.               or ( ( fname(posn)>='0' ) and ( fname(posn)<='9' ) )
  10587.               or ( fname(posn) = ':' ) -- always legal......
  10588.               or ( fname(posn) = ' ' ) -- eaten by no_blanks
  10589.               ) ;
  10590.           end loop ;
  10591.           if not ok then
  10592.             -- give invalid character in name error
  10593.             error(" Bad Character In Filename """ & compress(fname) & """." ,
  10594.               not_fatal_error , operator_wait , short_beep ) ;
  10595.           else
  10596.             -- Now, check for number of characters past '.'
  10597.               
  10598.             -- And finally, check for existance of file itself
  10599.             ok_to_read( fname , pfile_name , ok ) ;
  10600.             if ok then
  10601.               -- must turn pfile_name into correct format
  10602.               fname := no_file ; -- put blanks into file name
  10603.               for posn in 1 .. length(pfile_name) loop
  10604.                 -- note that we are not checking here for string too long ...
  10605.                 fname(posn) := pfile_name.data(posn);
  10606.               end loop ;
  10607.             else
  10608.               -- not ok
  10609.               error(" File """ & compress(fname) & """ does not exist." ,
  10610.                 not_fatal_error , operator_wait , short_beep ) ;
  10611.             end if;
  10612.           end if ;
  10613.         exit when ok ;
  10614.         end loop ; -- waiting for good file name or marker name ...
  10615.         if fname /= no_file then
  10616.           -- ok, we have a good file name to work...
  10617.           -- ready to work....
  10618.           clear_prompt( master_buffer ) ;
  10619.           goto_prompt_line_column( master_buffer , 1 , 1 );
  10620.           if marker_one = blank_marker and marker_two = blank_marker then
  10621.             put(" Copying in entire file """ & compress(fname) & """.");
  10622.           else
  10623.             put("Copying in file """ & compress(fname) & """ from ");
  10624.             if marker_one = blank_marker then
  10625.               put("the Beginning") ;
  10626.             else
  10627.               put("Marker """ & compress(marker_one) & """" ) ;
  10628.             end if ;
  10629.             put(" to ");
  10630.             if marker_two = blank_marker then
  10631.               put("the End.") ;
  10632.             else
  10633.               put("Marker """ & compress(marker_two) & """.");
  10634.             end if ;
  10635.           end if ;
  10636.           orig_line   := master_buffer.fixed_cursor.file_line_number ;
  10637.           orig_column := master_buffer.fixed_cursor.column_offset ;
  10638.           orig_screen_line := orig_line - master_buffer.top_screen_cursor.
  10639.                                                 file_line_number + 1 ;
  10640.           copy_file( master_buffer , fname , marker_one , marker_two ) ;
  10641.           jump_to_position ( master_buffer, orig_line , orig_column ,
  10642.                              false ) ;
  10643.           master_buffer.fixed_cursor.column_offset      :=
  10644.                num_leading_spaces(master_buffer,
  10645.                                   master_buffer.fixed_cursor.line_start ) + 1 ;
  10646.           show_screen( master_buffer ) ;
  10647.                         -- , master_buffer.fixed_cursor , orig_screen_line ) ;
  10648.           markers.marker_manager.load_marker( 
  10649.                        master_buffer.last_marked_position , current_position ) ;
  10650.         end if ;
  10651.       end copy_in_copy_file ;
  10652.        
  10653.     begin -- do_copy_command 
  10654.       clear_prompt( master_buffer ) ;
  10655.       goto_prompt_line_column( master_buffer , 1 , 1 ) ;
  10656.       put( copy_command_prompt ) ;
  10657.       case crt_windows.char_or_abort( ' ' , ' ' , 'B' , 'F' ) is
  10658.         when 'B'       => Copy_Text_Back_From_Copy_Buffer ( Master_Buffer ) ;
  10659.         when 'F'       => copy_in_copy_file   ;
  10660.         when others    => null     ;
  10661.       end case ;
  10662.       need_prompt := true ;
  10663.     end do_copy_command ;
  10664.      
  10665.     procedure do_quit_command ( partial , total : in out boolean ) is
  10666.       out_option : character ; -- the option selected by the user
  10667.       second_option : character ; -- secondary out option 
  10668.      
  10669.       function get_yes_no return boolean is
  10670.       begin -- get_yes_no
  10671.         return crt_windows.char_or_abort( 'N' , 'Y' , 'N' ) = 'Y' ;
  10672.       end get_yes_no ;
  10673.        
  10674.       procedure get_responses is
  10675.         valid_responses : crt_windows.character_set ;
  10676.         ok_answer       : boolean       ;
  10677.       begin -- get_responses 
  10678.         loop
  10679.           -- First, set up the valid user responses
  10680.           crt_windows.clear_set(valid_responses);
  10681.           valid_responses('B') := true ;
  10682.           valid_responses('E') := true ;
  10683.           valid_responses('R') := true ;
  10684.           valid_responses('W') := true ;
  10685.           clear_window( master_buffer ) ;
  10686.           set_prompt( master_buffer , 1 , 
  10687.                                     editor_customization.quit_command_prompt ) ;
  10688.           goto_line_column( master_buffer , 2 , 1 ) ;
  10689.           put_line("    B(egin editing another file without updating "
  10690.                                         & "current file");
  10691.           put_line("    E(xit without updating file");
  10692.           put_line("    R(eturn to the editor without updating file");
  10693.           put_line("    W(rite to a file name");
  10694.           if master_buffer.input_file_name /= no_file 
  10695.           or else master_buffer.output_file_name /= no_file then
  10696.             -- we had an input file name 
  10697.             put     ("    S(ave and update the ");
  10698.             if master_buffer.output_file_name = no_file then
  10699.               put     (                       "original file, """);
  10700.               put     (compress(master_buffer.input_file_name));
  10701.             else
  10702.               put     (                       "last output file, """);
  10703.               put     (compress(master_buffer.output_file_name));
  10704.             end if ;
  10705.             put_line("""");
  10706.             valid_responses('S') := true ;
  10707.           end if ;
  10708.           if master_buffer.copy_file_name /= no_file then
  10709.             -- we had a copy file name
  10710.             put     ("    X(change - Save into the copied in file, """);
  10711.             put     (compress(master_buffer.copy_file_name));
  10712.             put_line("""");
  10713.             valid_responses('X') := true ;
  10714.           end if ;
  10715.           if editor_entry_output_file_name  /= no_file
  10716.           and then editor_entry_output_file_name /= 
  10717.                         master_buffer.input_file_name then
  10718.             -- we had a copy file name
  10719.             put     ("    D(estination.  Save as the specified ");
  10720.             put     (     "Destination File """);
  10721.             put     (compress(editor_entry_output_file_name));
  10722.             put_line("""");
  10723.             valid_responses('D') := true ;
  10724.           end if ;
  10725.           if not only_editor then 
  10726.             -- we have to give the word processor as an option
  10727.             put_line("    P(rint a document without updating current file");
  10728.             valid_responses('P') := true ;
  10729.           end if ;
  10730.           put_line;
  10731.           put("  Option ? ");
  10732.           out_option := crt_windows.goodchar( valid_responses , 'R' );
  10733.           if ( ( out_option = 'B' ) or ( out_option = 'P' ) 
  10734.           or ( out_option = 'E' ) ) -- we are going to exit without updating
  10735.           or else ( ( out_option = 'S' ) and
  10736.                     ( master_buffer.copy_file_name /= no_file ) ) then
  10737.             -- we really should have the user confirm it
  10738.             put_line;
  10739.             put_line;
  10740.             put("  Are You Sure (Y/N) ? ");
  10741.             ok_answer := get_yes_no ;
  10742.           else 
  10743.             ok_answer := true ;
  10744.           end if ;
  10745.         exit when ok_answer ;
  10746.         end loop ;
  10747.       end get_responses ;
  10748.        
  10749.       function to_backup_name ( a_name : in ascii_text_file_name )
  10750.                                 return      ascii_text_file_name   is
  10751.         new_name : pstring ;
  10752.         new_ascii_name : ascii_text_file_name := no_file ;
  10753.         posn     : integer ;
  10754.       begin -- to_backup_name 
  10755.         new_name := compress( a_name ) ;
  10756.         posn := position('.' , new_name ) ;
  10757.         if posn = 0 then
  10758.           posn := length(new_name) + 1 ;
  10759.         end if ;
  10760.         -- Now, posn is where we will put the .bak ending 
  10761.         if posn + default_backup_ending'length - 1 
  10762.                     > ascii_text_file_name'length then
  10763.           -- need to shorten the starting string
  10764.           posn := ascii_text_file_name'length 
  10765.                     - default_backup_ending'length + 1 ;
  10766.         end if ;
  10767.         set_length( new_name , posn + default_backup_ending'length - 1 ) ;
  10768.         for place in 1 .. default_backup_ending'length loop
  10769.           new_name.data( posn + place - 1 ) := default_backup_ending( place ) ;
  10770.         end loop ;
  10771.         for place in 1 .. length( new_name ) loop
  10772.           new_ascii_name ( place ) := new_name.data ( place ) ;
  10773.         end loop ;
  10774.         return new_ascii_name ;
  10775.       end to_backup_name ;
  10776.        
  10777.       procedure get_output_file_name is 
  10778.         done : boolean ;
  10779.       begin -- get_output_file_name
  10780.         -- They typed in 'W' for write to file name.  Get a file name
  10781.         -- and confirm that it is available for writing.  Then, 
  10782.         -- set editor_requested_output_file_name.  If they hit a 
  10783.         -- return, then we will set the second_option to 'A' for abort
  10784.         -- as well as the out_option 
  10785.         --
  10786.         -- Note that we must know exactly what the screen looks like
  10787.         --
  10788.         done := false ;
  10789.         loop
  10790.           clear_end_of_screen( master_buffer , 13 , 1 ) ;
  10791.           goto_line_column   ( master_buffer , 13 , 1 ) ;
  10792.           put("  Enter Output File Name ( or <return> to abort ) => ") ;
  10793.           editor_requested_output_file_name := 
  10794.                           get_output_filename_or_return ;
  10795.           if editor_requested_output_file_name = blank_file_name then
  10796.             -- we want to return to the editor
  10797.             out_option := 'A' ;
  10798.             second_option := 'A' ;
  10799.             done := true ;
  10800.           elsif editor_requested_output_file_name( 1 ) = ascii.esc then
  10801.             -- an error, the file name did not exist
  10802.             error(" File """ 
  10803.                                 & compress(editor_requested_output_file_name
  10804.                      ( 2 .. editor_requested_output_file_name'length ) )
  10805.                                 & """ is an invalid name." ,
  10806.                    not_fatal_error ,
  10807.                    operator_wait ,
  10808.                    short_beep ) ;
  10809.           elsif file_exists ( editor_requested_output_file_name ) then
  10810.             -- we must confirm that they want to save it
  10811.             put_line;
  10812.             put_line;
  10813.             put_line("  File """ & compress(editor_requested_output_file_name)
  10814.                             & """ already exists.  ");
  10815.             put_line;
  10816.             -- put     ("  Rename it to """ &
  10817.                         -- compress( to_backup_name
  10818.                                   -- ( editor_requested_output_file_name ) 
  10819.                                 -- ) & """ and continue (Y/N) ? ");
  10820.             put     ("  Delete """ &
  10821.                         compress( editor_requested_output_file_name  
  10822.                                 ) & """ and continue (Y/N) ? ");
  10823.             done := get_yes_no ; -- if they say "Y", then we will just leave.
  10824.             -- when it comes time to writing, we will automatically rename
  10825.             -- otherwise, if they say no, then re-ask the question for a
  10826.             -- file name 
  10827.           else
  10828.             done := true ; -- because it does not exist...
  10829.           end if ;
  10830.         -- need to set the default environment
  10831.         exit when done ;
  10832.         end loop ;
  10833.       end get_output_file_name ;
  10834.        
  10835.       procedure get_secondary_responses is
  10836.         -- we have a response from the user which calls for another
  10837.         -- response
  10838.         valid_responses : crt_windows.character_set ;
  10839.         ok_answer       : boolean       ;
  10840.       begin -- get_secondary_responses
  10841.         -- not B,E,P,R
  10842.         -- First, figure out the file name for output 
  10843.         -- If 'W' we must ask for it.
  10844.         if out_option = 'W' then
  10845.           get_output_file_name ;
  10846.         end if ;
  10847.         if out_option /= 'A' then
  10848.           -- if they did 'W' and then changed their mind, we changed
  10849.           -- out_option to 'A' 
  10850.           case out_option is
  10851.             when 'S' => if master_buffer.output_file_name = no_file then
  10852.                           editor_requested_output_file_name 
  10853.                                   := master_buffer.input_file_name ;
  10854.                         else
  10855.                           editor_requested_output_file_name
  10856.                                   := master_buffer.output_file_name ;
  10857.                         end if ;
  10858.             when 'X' => editor_requested_output_file_name 
  10859.                                   := master_buffer.copy_file_name  ;
  10860.             when 'D' => editor_requested_output_file_name 
  10861.                                   := editor_entry_output_file_name ;
  10862.             when 'W' => null ; -- file name already set .
  10863.             when others => null ; -- I know it can't get here
  10864.           end case ;
  10865.           -- Now, get the secondary output option
  10866.           crt_windows.clear_set(valid_responses);
  10867.           valid_responses('A') := true ;
  10868.           valid_responses('B') := true ;
  10869.           valid_responses('E') := true ;
  10870.           valid_responses('R') := true ;
  10871.           clear_end_of_screen( master_buffer , 13 , 1 ) ;
  10872.           goto_line_column   ( master_buffer , 13 , 1 ) ;
  10873.           put     ("  What do you want to do after saving the file as """);
  10874.           put     (            compress(editor_requested_output_file_name));
  10875.           put_line(                                                  """.");
  10876.           put_line;
  10877.           put_line("    A(bort the current output options & return to editor");
  10878.           put_line("    B(egin editing another file");
  10879.           put_line("    E(xit the editor");
  10880.           put_line("    R(eturn to the editor to continue editing the current "
  10881.                                                   & "file");
  10882.           if not only_editor then 
  10883.             -- we have to give the word processor as an option
  10884.             put_line("    I(mmediately Print the current document using"
  10885.                                           & " default options");
  10886.             valid_responses('I') := true ;
  10887.             put_line("    P(rint a different document");
  10888.             valid_responses('P') := true ;
  10889.           end if ;
  10890.           put_line;
  10891.           put("  Enter Secondary Option ? ");
  10892.           second_option := crt_windows.goodchar( valid_responses , 'R' ) ;
  10893.           -- Now, figure out the partial and total quit responses
  10894.           case second_option is
  10895.             when 'A' => null ; -- take care of by caller 
  10896.             when 'B' => partial := true  ;
  10897.                         total   := false ;
  10898.             when 'E' => partial := true  ;
  10899.                         total   := true  ;
  10900.                         what_to_run_next := master_menu ;
  10901.             when 'R' => partial := false ;
  10902.                         total   := false ;
  10903.             when 'I' => partial := true  ;
  10904.                         total   := true  ;
  10905.                         what_to_run_next := format_editor_file ;
  10906.             when 'P' => partial := true  ;
  10907.                         total   := true  ;
  10908.                         what_to_run_next := text_formatter ;
  10909.             when others => null ; -- I know it can't get here
  10910.           end case;
  10911.         end if ;
  10912.       end get_secondary_responses ;
  10913.  
  10914.       procedure redo_screen is
  10915.       begin -- redo_screen 
  10916.         -- reshow the screen
  10917.         restore_shift ;
  10918.         jump_to_position(master_buffer,
  10919.                                 master_buffer.fixed_cursor.file_line_number,
  10920.                                 master_buffer.fixed_cursor.column_offset );
  10921.         -- that moves us back to the correct place in the file
  10922.         need_prompt := true  ; 
  10923.         partial := false ;
  10924.         total   := false ;
  10925.       end redo_screen ;
  10926.        
  10927.       Procedure Output_Text ( Buffer       : in out An_Editor_Buffer ;
  10928.                               output_range : in text_range           ;
  10929.                               output_filenm: in ascii_text_file_name ;
  10930.                               successfull  : out boolean             ) is
  10931.         -- Output the range of text within the buffer to the output file
  10932.         -- for now, write entire file
  10933.         unable_to_continue : exception ;
  10934.         text_output_file : text_io.file_type ;
  10935.         output_line      : string ( 1 .. max_column_number ) ;
  10936.         output_length    : Integer := 0 ;
  10937.         length_goal      : Integer := 0 ;
  10938.         leading_spaces   : Integer := 0 ;
  10939.         out_lines        : Integer := 0 ;
  10940.         first_line       : boolean := true ;
  10941.          
  10942.         procedure out_pstring ( s : in pstring ) is
  10943.         begin -- out_pstring 
  10944.           text_io.put_line( text_output_file , s.data( 1 .. length(s) ) ) ;
  10945.         end out_pstring ;
  10946.          
  10947.         procedure out_string is
  10948.         begin -- out_string 
  10949.           if first_line then
  10950.             first_line := false ;
  10951.           else
  10952.             text_io.new_line( text_output_file ) ;
  10953.           end if ;
  10954.           for space_number in 1 .. leading_spaces loop
  10955.             text_io.put( text_output_file , ' ' ) ;
  10956.           end loop ;
  10957.           if output_length > 3 then
  10958.             text_io.put(text_output_file, output_line ( 3..output_length - 1 ));
  10959.           end if ;
  10960.           out_lines := out_lines + 1 ;
  10961.           if out_lines mod 100 = 0 then
  10962.             put('.');
  10963.           end if ;
  10964.         end out_string ;
  10965.          
  10966.         procedure do_file_open is
  10967.           real_file_name   : ascii_text_file_name ;
  10968.           ok               : boolean ;
  10969.         begin -- do_file_open 
  10970.           -- Step 1 : Open the output file
  10971.           real_file_name := output_filenm ;
  10972.           open_for_write( text_output_file , real_file_name , ok ) ;
  10973.           if ok then
  10974.             -- give some statistics
  10975.             put("Writing file """ & compress( real_file_name ) & """ => " );
  10976.             buffer.output_file_name := real_file_name ;
  10977.             editor_requested_output_file_name := real_file_name ;
  10978.           else
  10979.             -- first, give an error message
  10980.             error( " Unable to Create File """ & string_library.compress(output_filenm)
  10981.                                           & """." ,
  10982.                  not_fatal_error , operator_wait , short_beep ) ;
  10983.             -- then, return
  10984.             raise unable_to_continue ;
  10985.           end if ;
  10986.         end do_file_open ;
  10987.          
  10988.         procedure do_environment is
  10989.           a_pstring        : pstring ;
  10990.           env_code         : integer ;
  10991.           put_it_out       : boolean ;
  10992.           check_name       : ascii_text_file_name ;
  10993.         begin -- do_environment 
  10994.           put_it_out := buffer.pagezero.save_envirn ;
  10995.           if not put_it_out then
  10996.             -- see if we need to do anything because it is the default
  10997.             -- environment file name 
  10998.             -- work with default_environment_file_name 
  10999.             -- and editor_requested_output_file_name 
  11000.             check_name := editor_requested_output_file_name ;
  11001.             loop
  11002.               if check_name = editor_requested_output_file_name then
  11003.                 put_it_out := true ;
  11004.               end if ;
  11005.             exit when put_it_out or ( check_name = no_file ) ;
  11006.               check_name( 1 .. check_name'length - 1 )
  11007.                         := check_name( 2 .. check_name'length ) ;
  11008.               check_name( check_name'length ) := ' ' ;
  11009.             end loop ;
  11010.           end if ;
  11011.           -- Step 2: Output The Environment
  11012.           if put_it_out then
  11013.             env_code := 0 ;
  11014.             loop
  11015.               environment_input_output.convert_header_to_string 
  11016.                           ( buffer.pagezero , env_code , a_pstring ) ;
  11017.             exit when env_code <= 0 ;
  11018.               if env_code = 1 then
  11019.                 put("# ");
  11020.               end if ;
  11021.               out_pstring( a_pstring ) ;
  11022.             end loop ;
  11023.           end if ;
  11024.         end do_environment ;
  11025.          
  11026.         procedure char_out ( c : in editor_globals.extended_character ) is
  11027.           -- add this character to the output_line.  When we hit the
  11028.           -- length_goal, then call out_string to process the line for
  11029.           -- output ... 
  11030.           -- output_line      : string ( 1 .. max_column_number ) ;
  11031.           -- output_length    : Integer := 0 ;
  11032.           -- length_goal      : Integer := 0 ;
  11033.         begin -- char_out 
  11034.           output_length := output_length + 1 ;
  11035.           if output_length < 3 then
  11036.             if output_length = 1 then
  11037.               length_goal := c + 3 ;
  11038.             else
  11039.               leading_spaces := c ;
  11040.             end if ;
  11041.           else
  11042.             if output_length < length_goal then
  11043.               output_line( output_length ) := character'val( c ) ;
  11044.             else
  11045.               -- need to just output the line...
  11046.               out_string ;
  11047.               output_length := 0 ;
  11048.             end if ;
  11049.           end if ;
  11050.         end char_out ;
  11051.          
  11052.         procedure do_a_block ( what : topush ; blockn : integer ) is
  11053.           block_of_data : block   ;
  11054.           successfull   : boolean ;
  11055.         begin
  11056.           buffer_block_io.getblock( buffer , 
  11057.                                     what , 
  11058.                                     block_of_data , blockn , successfull ) ;
  11059.           if successfull then
  11060.             for posn in 0 .. block_minus loop
  11061.               char_out( block_of_data(posn).data ) ; 
  11062.             end loop ;
  11063.           else
  11064.             error( " Unable to read temporary file for output ." ,
  11065.                  not_fatal_error , operator_wait , short_beep ) ;
  11066.             raise unable_to_continue ;
  11067.           end if ;
  11068.         end ;
  11069.          
  11070.       begin -- output_text
  11071.         clear_window( buffer ) ;
  11072.         clear_prompt( buffer ) ;
  11073.         goto_line_column( buffer , 1 , 3 ) ;
  11074.         -- Open the file, then, put out the environment
  11075.         -- and Then, we have three areas to work with: the top blocks, the
  11076.         -- actual text buffer, and then the bottom blocks 
  11077.         do_file_open ;
  11078.         do_environment ;
  11079.         -- Do the Top Blocks
  11080.         for blockn in 1 .. buffer.prestopblock loop 
  11081.           do_a_block( thetop , blockn ) ;
  11082.         end loop ;
  11083.         -- Do The Center Information
  11084.         for posn in 1 .. buffer.bufcount loop
  11085.           char_out( buffer.e_buf( posn ).data ) ;
  11086.         end loop ;
  11087.         -- Do The Bottom Blocks 
  11088.         for blockn in reverse 1 .. buffer.presbotblock loop
  11089.           do_a_block( thebot , blockn ) ;
  11090.         end loop ;
  11091.         put_line ;
  11092.         put("  Your file is ");
  11093.         put( out_lines , 1 ) ;
  11094.         put(" lines long.");
  11095.         -- Close the File
  11096.         -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  11097.         -- On the Wicat, we need to put a new_line in, even if the
  11098.         -- file does not end with a new_line....
  11099.         -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  11100.         text_io.new_line( text_output_file ) ;
  11101.         text_io.close( text_output_file ) ;
  11102.         successfull := true ;
  11103.       exception
  11104.         when unable_to_continue => successfull := false ;
  11105.       end output_text ;
  11106.        
  11107.       procedure do_output_procedures is
  11108.         new_backup_name : ascii_text_file_name ;
  11109.         out_range       : text_range           ;
  11110.         successfull     : boolean              ;
  11111.         old_posn        : cursor_position      := master_buffer.fixed_cursor ;
  11112.       begin -- do_output_procedures
  11113.         -- Here we are with editor_requested_output_file set
  11114.         -- please output the file 
  11115.         -- if a file exists with that same name, turn it into .bak
  11116.         -- finish reading in the input file 
  11117.         clear_window( master_buffer ) ;
  11118.         clear_prompt( master_buffer ) ;
  11119.         if master_buffer.still_reading_input_file then
  11120.           jump_to_position( master_buffer , max_line_number , 0 , false ) ;
  11121.         end if ;
  11122.         -- Now, take care of the backup file if necessary
  11123.         if file_exists(editor_requested_output_file_name) then
  11124.           -- must turn it into a backup file 
  11125.           new_backup_name := to_backup_name( editor_requested_output_file_name);
  11126.           -- do_purge(new_backup_name);  -- purge the old file if necessary
  11127.           --rename_file( editor_requested_output_file_name , new_backup_name ) ;
  11128.           do_purge( editor_requested_output_file_name ) ;
  11129.         end if ;
  11130.         Out_Range.Lo_Position.Line   := 1 ;
  11131.         Out_Range.Lo_Position.Column := 1 ;
  11132.         Out_Range.Hi_Position.Line   := Max_Line_Number ;
  11133.         Out_Range.Hi_Position.Column := Max_Column_Number ;
  11134.         output_text( master_buffer , 
  11135.                      out_range , 
  11136.                      editor_requested_output_file_name ,
  11137.                      successfull ) ;
  11138.         if not successfull then
  11139.           second_option := 'R' ;
  11140.         end if ;
  11141.         if second_option = 'R' then
  11142.           -- must move back to the correct place
  11143.           jump_to_position ( master_buffer ,
  11144.                              old_posn.file_line_number ,
  11145.                              old_posn.column_offset ,
  11146.                              false ) ;
  11147.         end if ;
  11148.       end do_output_procedures ;
  11149.        
  11150.     -- type_what_to_run_next is ( master_menu , text_editor , text_formatter ,
  11151.                                     -- operating_system , format_editor_file ,
  11152.                                     -- edit_formatter_file ) ;
  11153.                            
  11154.     begin -- do_quit_command 
  11155.       store_shift ; -- and only restore if we redo the screen
  11156.       get_responses ;
  11157.       if out_option = 'R' then
  11158.         redo_screen ;
  11159.       elsif ( out_option = 'B' ) or ( out_option = 'E' ) 
  11160.                                  or ( out_option = 'P' ) then
  11161.         -- we are throwing away the current work.
  11162.         partial := true ;
  11163.         total   := ( out_option = 'E' ) or ( out_option = 'P' ) ;
  11164.         if out_option = 'P' then
  11165.           what_to_run_next := text_formatter ;
  11166.         else 
  11167.           what_to_run_next := master_menu ;
  11168.         end if ;
  11169.         clear_window(master_buffer);
  11170.         clear_prompt(master_buffer);
  11171.         if ( out_option = 'E' ) or ( out_option = 'P' ) then
  11172.           dispose_buffer( master_buffer ) ;
  11173.         else
  11174.           -- must tell editor to ask for a new file name
  11175.           editor_entry_input_file_name := blank_file_name ;
  11176.         end if ;
  11177.       else
  11178.         -- not B,E,P,R
  11179.         -- so we need to know their follow-on response
  11180.         get_secondary_responses ;
  11181.         if second_option = 'A' then
  11182.           redo_screen ; -- because they changed their mind...
  11183.         else
  11184.           do_output_procedures ;
  11185.           if second_option = 'R' then
  11186.             -- we need to redo the screen and then return
  11187.             redo_screen ;
  11188.           else
  11189.             -- we must clear the screen, close the buffer, and exit
  11190.             clear_window(master_buffer);
  11191.             clear_prompt(master_buffer);
  11192.             if second_option = 'B' then
  11193.               -- must tell editor to ask for a new file name
  11194.               editor_entry_input_file_name := blank_file_name ;
  11195.             else
  11196.               dispose_buffer( master_buffer ) ;
  11197.             end if ;
  11198.           end if ;
  11199.         end if ;
  11200.       end if ; 
  11201.     end do_quit_command ;
  11202.      
  11203.   begin -- Editor_Files
  11204.     -- EDITFILE by SAIC/Clearwater Editor File Packages        22 Jan 85
  11205.     -- INITIAL  by SAIC/Clearwater Editor Initialize Package   26 Dec 84
  11206.     -- COPY     by SAIC/Clearwater Editor Copy Command         26 Dec 84
  11207.     -- QUIT     by SAIC/Clearwater Editor QuittCommand         22 Jan 85
  11208.     null ;
  11209.   end Editor_Files ;
  11210.     
  11211.   --$$$- EDITFILE
  11212.  
  11213. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  11214. --move
  11215. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  11216.  
  11217.   --$$$+ MOVE
  11218.    
  11219.   --
  11220.   -- File 022
  11221.   --
  11222.   -- Editor Written By Robert S. Cymbalski
  11223.   --                   Science Applications International Corporation
  11224.   --                   Energy Systems Group
  11225.   --                   Ada Software Development Project Team
  11226.   --                   2280 U.S. Highway 19 North, Suite 120
  11227.   --                   Clearwater, Florida  33575
  11228.   --
  11229.   -- Movement Routine Written 12 Nov 84 - RSC
  11230.   --
  11231.   --
  11232.   -- Editor Revised from text Copyright (c) 1984 , R.S.Cymbalski
  11233.   -- 
  11234.       
  11235.   with string_library  ;
  11236.   use  string_library  ;
  11237.    
  11238.   with crt_customization ;
  11239.   use  crt_customization ;
  11240.   use  crt               ;
  11241.   use  editor_customization ;
  11242.    
  11243.   with crt_windows     ;
  11244.    
  11245.   with Wordp_Globals   ;
  11246.   use  Wordp_Globals   ;
  11247.  
  11248.   with editor_globals         ;
  11249.   use  editor_globals         ;
  11250.    
  11251.   with edit_windows           ;
  11252.   use  edit_windows           ;
  11253.    
  11254.   with buffer_package  ;
  11255.   use  buffer_package  ;
  11256.   use  buffer_lines    ;
  11257.    
  11258.   with editor_misc            ;
  11259.   use  editor_misc            ;
  11260.   use  copy_package           ;
  11261.      
  11262.   with editor_more_packages   ;
  11263.   use  editor_more_packages   ;
  11264.    
  11265.   with markers                ;
  11266.   use  markers                ;
  11267.   use  text_position_handler  ;
  11268.    
  11269.   with debugger ;
  11270.    
  11271.   package movement_package is
  11272.    
  11273.     -- ISO Editor Commands
  11274.      
  11275.     Procedure CURSOR_HORIZONTAL ( COLUMNS_TO_MOVE_RIGHT : in a_repeat_factor ;
  11276.                                   show_cursor_at_end    : in boolean := true ) ;
  11277.       -- free cursor movement within window.  The cursor can move right
  11278.       -- to the last possible editable column.  If it passes that, it
  11279.       -- will scroll to the next line.  At the end of the file it stops.
  11280.       -- When going backwards, it can go to the first column.  If it passes
  11281.       -- that, then it will move to the position following the last 
  11282.       -- character on the previous line.  It stops at the beginning of
  11283.       -- the file.   
  11284.      
  11285.     Procedure CURSOR_VERTICAL ( LINES_TO_MOVE_DOWN : in a_repeat_factor ;
  11286.                                 show_cursor_at_end : in boolean := true ) ;
  11287.       -- free cursor movement within window
  11288.        
  11289.     Procedure MOVE_HORIZONTAL ( COLUMNS_TO_MOVE_RIGHT : in a_repeat_factor ;
  11290.                                 show_cursor_at_end    : in boolean := true ) ;
  11291.       -- ***  bound cursor movement / scroll if necessary *** --
  11292.       -- When it passes the position following the last character on
  11293.       -- a line, it moves to the first character position on the next
  11294.       -- line.  
  11295.      
  11296.     Procedure MOVE_VERTICAL ( LINES_TO_MOVE_DOWN : in a_repeat_factor ;
  11297.                               show_cursor_at_end : in boolean := true ) ;
  11298.       -- ***  bound cursor vertical movement / scroll if necessary *** --
  11299.         
  11300.     type type_of_pattern is ( word_pattern , tab_pattern , paragraph_pattern ,
  11301.                               line_start_pattern , line_end_pattern        ) ;
  11302.      
  11303.     function  find_forward ( pattern : in  type_of_pattern ;
  11304.                              number_to_find : in a_repeat_factor := 1 
  11305.                              ) return text_position ;
  11306.      
  11307.     function find_backward ( pattern : in  type_of_pattern ;
  11308.                              number_to_find : in a_repeat_factor := 1 
  11309.                              ) return text_position ;
  11310.      
  11311.     Procedure position ( place : in text_position ;
  11312.                          show_cursor_at_end : boolean := true ) ;
  11313.       -- move the cursor to the specified location.  Update the screen 
  11314.       -- unless requested otherwise
  11315.      
  11316.     -- SAIC Editor Commands
  11317.      
  11318.     procedure do_move_command ( movement_command : in an_editor_command ;
  11319.                         repeat_factor     : in a_repeat_factor    ) ; 
  11320.    
  11321.     procedure do_jump_command ;
  11322.      
  11323.     go_forward         :  boolean           ;
  11324.    
  11325.   private
  11326.     
  11327.     in_deletion     : boolean := false ;
  11328.     append_deletion : boolean := false ;
  11329.      
  11330.     Append_Command_Prompt : string ( 1 .. 71 ) :=
  11331.       " {Appending Deletion}: <Moving Cmds>, <Append Tog>, <Accept>, <Reject> ";
  11332.      
  11333.     StrtDel_column : column_position ;
  11334.     StrtDel_line   : line_number     ;
  11335.     StrtDel_Pos    : text_position   ;
  11336.     EndDelt_column : column_position ;
  11337.     EndDelt_line   : line_number     ;
  11338.     EndDelt_Pos    : text_position   ;
  11339.    
  11340.   end movement_package ;
  11341.    
  11342.   package body movement_package is
  11343.    
  11344.     -- Support Routines.
  11345.      
  11346.     procedure to_beginning is
  11347.     begin -- jump to the beginning of the file
  11348.       jump_to_position ( master_buffer , 1 , 0 , false ) ;
  11349.     end to_beginning ;
  11350.      
  11351.     procedure to_end is
  11352.     begin -- jump to the end of the file
  11353.       jump_to_position ( master_buffer , line_number'last , 0 , false ) ;
  11354.     end to_end ;
  11355.      
  11356.     -- ISO Editor Commands
  11357.      
  11358.     Procedure CURSOR_HORIZONTAL ( COLUMNS_TO_MOVE_RIGHT : in a_repeat_factor ;
  11359.                                   show_cursor_at_end    : in boolean := true) is
  11360.       -- free cursor movement within window.  The cursor can move right
  11361.       -- to the last possible editable column.  If it passes that, it
  11362.       -- will scroll to the next line.  At the end of the file it stops.
  11363.       -- When going backwards, it can go to the first column.  If it passes
  11364.       -- that, then it will move to the position following the last 
  11365.       -- character on the previous line.  It stops at the beginning of
  11366.       -- the file.   
  11367.       number_to_move : a_repeat_factor ;
  11368.       columns_remaining_on_line : column_position ;
  11369.     begin -- cursor_horizontal 
  11370.       if columns_to_move_right > 0 then
  11371.         -- forward
  11372.         number_to_move := columns_to_move_right ;
  11373.         columns_remaining_on_line := max_column_number 
  11374.                                    - master_buffer.fixed_cursor.column_offset ;
  11375.         while number_to_move > columns_remaining_on_line loop
  11376.           -- need to simply move to the next line...
  11377.           -- and columns_remaining_on_line could be as small as zero...
  11378.           if cursor_forward_line then
  11379.             -- ok, we moved one line forward
  11380.             number_to_move := number_to_move - columns_remaining_on_line 
  11381.                                              - 1 ;
  11382.               -- the minus one above is for the movement past the last 
  11383.               -- character on the line 
  11384.             master_buffer.fixed_cursor.column_offset := 1 ;
  11385.             columns_remaining_on_line := max_column_number - 1 ;
  11386.           else
  11387.             -- we were unable to move any further
  11388.             to_end ; -- so simply move to the end of the file 
  11389.             number_to_move := 0 ;
  11390.           end if ;
  11391.         end loop ;
  11392.         if number_to_move > 0 then
  11393.           -- we only get here if we know we can stay on this line...
  11394.           master_buffer.fixed_cursor.column_offset :=
  11395.                   master_buffer.fixed_cursor.column_offset + number_to_move ;
  11396.         end if ;
  11397.       elsif columns_to_move_right < 0 then
  11398.         -- backward
  11399.         number_to_move := - columns_to_move_right ;
  11400.         columns_remaining_on_line := 
  11401.                                   master_buffer.fixed_cursor.column_offset - 1 ;
  11402.         while number_to_move > columns_remaining_on_line loop
  11403.           -- need to simply move to the next line...
  11404.           -- and columns_remaining_on_line could be as small as zero...
  11405.           if cursor_backward_line then
  11406.             -- ok, we moved one line backward
  11407.             number_to_move := number_to_move - columns_remaining_on_line 
  11408.                                              - 1 ;
  11409.               -- the minus one above is for the movement past the last 
  11410.               -- character on the line 
  11411.             master_buffer.fixed_cursor.column_offset
  11412.               := num_leading_spaces( master_buffer ,
  11413.                                      master_buffer.fixed_cursor.line_start )
  11414.                + line_length( master_buffer , 
  11415.                               master_buffer.fixed_cursor.line_start ) + 1 ;
  11416.             columns_remaining_on_line := 
  11417.                                   master_buffer.fixed_cursor.column_offset - 1 ;
  11418.           else
  11419.             -- we were unable to move any further
  11420.             to_beginning ; -- so simply move to the start of the file
  11421.             number_to_move := 0 ;
  11422.           end if ;
  11423.         end loop ;
  11424.         if number_to_move > 0 then
  11425.           -- need to move within the current line
  11426.           master_buffer.fixed_cursor.column_offset :=
  11427.                 master_buffer.fixed_cursor.column_offset - number_to_move ;
  11428.         end if ;
  11429.       end if ;
  11430.       master_buffer.fixed_cursor.buffer_position := 0 ;
  11431.       if show_cursor_at_end then
  11432.         show_cursor ( master_buffer ) ;
  11433.       end if ;
  11434.     end cursor_horizontal ;
  11435.      
  11436.     Procedure CURSOR_VERTICAL ( LINES_TO_MOVE_DOWN : in a_repeat_factor ;
  11437.                                 show_cursor_at_end : in boolean := true ) is
  11438.       -- free cursor movement within window
  11439.       number_to_move : a_repeat_factor ;
  11440.       Old_Column     : column_position ;
  11441.     begin -- cursor_vertical 
  11442.       number_to_move := lines_to_move_down ;
  11443.       master_buffer.fixed_cursor.buffer_position := 0 ;
  11444.       Old_Column := master_buffer.fixed_cursor.column_offset ;
  11445.       if lines_to_move_down > 0 then
  11446.         -- forward
  11447.         while number_to_move > 0 loop
  11448.           if cursor_forward_line then
  11449.             -- ok.....
  11450.             number_to_move := number_to_move - 1 ;
  11451.           else
  11452.             number_to_move := 0 ;
  11453.           end if ;
  11454.         end loop ;
  11455.       elsif lines_to_move_down < 0 then
  11456.         -- backward
  11457.         while number_to_move < 0 loop
  11458.           if cursor_backward_line then
  11459.             -- ok
  11460.             number_to_move := number_to_move + 1 ;
  11461.           else
  11462.             number_to_move := 0 ;
  11463.           end if ;
  11464.         end loop ;
  11465.       end if ;
  11466.       master_buffer.fixed_cursor.column_offset := Old_Column ;
  11467.       if show_cursor_at_end then
  11468.         show_cursor ( master_buffer ) ;
  11469.       end if ;
  11470.     end cursor_vertical ;
  11471.      
  11472.     procedure left_and_right_columns(which_buffer : in an_editor_buffer;
  11473.                                      left_most_column  : out column_position; 
  11474.                                      right_most_column : out column_position) is
  11475.       temp_left : column_position ;
  11476.     begin -- left_and_right_columns
  11477.       temp_left        := num_leading_spaces(which_buffer,
  11478.                                           which_buffer.fixed_cursor.line_start)
  11479.                                              + 1 ;
  11480.       left_most_column  := temp_left ;
  11481.       right_most_column := temp_left 
  11482.                               + line_length(which_buffer ,
  11483.                                          which_buffer.fixed_cursor.line_start);
  11484.     end left_and_right_columns ;
  11485.  
  11486.     procedure set_cursor_position is
  11487.       target_col         : column_position     ;
  11488.       first_col          ,
  11489.       last_col           : column_position     ;
  11490.     begin -- set_cursor 
  11491.       left_and_right_columns( master_buffer , first_col , last_col ) ;
  11492.       if master_buffer.fixed_cursor.column_offset < first_col then
  11493.         master_buffer.fixed_cursor.buffer_position := 0 ;
  11494.       elsif master_buffer.fixed_cursor.column_offset >= last_col then
  11495.         master_buffer.fixed_cursor.buffer_position := 0 ; 
  11496.       else
  11497.         master_buffer.fixed_cursor.buffer_position := 
  11498.                         master_buffer.fixed_cursor.line_start 
  11499.                         + master_buffer.fixed_cursor.column_offset 
  11500.                         - first_col + 2 ;
  11501.       end if ;
  11502.     end set_cursor_position ;
  11503.  
  11504.     function char_at_position return character is
  11505.       -- return the character at the current cursor position 
  11506.     begin
  11507.       set_cursor_position ;
  11508.       if master_buffer.fixed_cursor.buffer_position = 0 then
  11509.         return ascii.cr ;
  11510.       else
  11511.         return character'val ( master_buffer.e_buf(master_buffer.fixed_cursor.
  11512.                                  buffer_position).data ) ;
  11513.       end if ;
  11514.     end char_at_position ;
  11515.      
  11516.     Procedure MOVE_HORIZONTAL ( COLUMNS_TO_MOVE_RIGHT : in a_repeat_factor ;
  11517.                                 show_cursor_at_end    : in boolean := true ) is
  11518.       -- ***  bound cursor movement / scroll if necessary *** --
  11519.       -- When it passes the position following the last character on
  11520.       -- a line, it moves to the first character position on the next
  11521.       -- line.  
  11522.       --
  11523.       -- This means that we must move the cursor within the bounds of the
  11524.       -- first character on the line ( which is at column
  11525.       -- num_leading_spaces( master_buffer 
  11526.       -- , master_buffer.fixed_cursor.line_start)+1
  11527.       -- and the position following the last position on the line, which is
  11528.       -- line_length( master_buffer , master_buffer.fixed_cursor.line_start ) 
  11529.       -- to the right of the first valid position 
  11530.       number_to_move : a_repeat_factor ;
  11531.       left_most_column ,
  11532.       right_most_column ,
  11533.       columns_remaining_on_line : column_position ;
  11534.     begin -- move_horizontal
  11535.       left_and_right_columns(master_buffer,left_most_column,right_most_column);
  11536.       if columns_to_move_right > 0 then
  11537.         -- forward. Note that if we are not currently within the text area,
  11538.         -- then the first movement will move to that position 
  11539.         number_to_move := columns_to_move_right ;
  11540.         if master_buffer.fixed_cursor.column_offset >= right_most_column then
  11541.           columns_remaining_on_line := 0 ; 
  11542.         elsif master_buffer.fixed_cursor.column_offset >= left_most_column then
  11543.           columns_remaining_on_line := right_most_column 
  11544.                                   - master_buffer.fixed_cursor.column_offset ;
  11545.         else
  11546.           columns_remaining_on_line := right_most_column - left_most_column;
  11547.           number_to_move := number_to_move - 1 ; -- to get to first character
  11548.           master_buffer.fixed_cursor.column_offset := left_most_column ;
  11549.         end if ;
  11550.         while number_to_move > columns_remaining_on_line loop
  11551.           -- loop through each of the lines first
  11552.           -- need to simply move to the next line...
  11553.           -- and columns_remaining_on_line could be as small as zero...
  11554.           if cursor_forward_line then
  11555.             -- ok, we moved one line forward
  11556.             number_to_move := number_to_move - columns_remaining_on_line 
  11557.                                              - 1 ;
  11558.               -- the minus one above is for the movement past the last 
  11559.               -- character on the line 
  11560.             left_and_right_columns(master_buffer,
  11561.                                    left_most_column,right_most_column);
  11562.             master_buffer.fixed_cursor.column_offset := left_most_column ;
  11563.             columns_remaining_on_line := right_most_column - left_most_column;
  11564.           else
  11565.             -- we were unable to move any further
  11566.             to_end ; -- so simply move to the end of the file 
  11567.             number_to_move := 0 ;
  11568.           end if ;
  11569.         end loop ;
  11570.         if number_to_move > 0 then
  11571.           -- need to move within the current line
  11572.           master_buffer.fixed_cursor.column_offset :=
  11573.                 master_buffer.fixed_cursor.column_offset + number_to_move ;
  11574.         end if ;
  11575.       elsif columns_to_move_right < 0 then
  11576.         -- backward
  11577.         number_to_move := - columns_to_move_right ;
  11578.         -- Note that if we are not currently within the text area,
  11579.         -- then the first movement will move to that position 
  11580.         if master_buffer.fixed_cursor.column_offset > right_most_column then
  11581.           columns_remaining_on_line := right_most_column - left_most_column;
  11582.           number_to_move := number_to_move - 1 ; -- to get to first character
  11583.           master_buffer.fixed_cursor.column_offset := right_most_column ;
  11584.         elsif master_buffer.fixed_cursor.column_offset > left_most_column then
  11585.           columns_remaining_on_line := master_buffer.fixed_cursor.column_offset
  11586.                                        - left_most_column ;
  11587.         else
  11588.           -- here in the left margin...
  11589.           columns_remaining_on_line := 0 ; 
  11590.         end if ;
  11591.         while number_to_move > columns_remaining_on_line loop
  11592.           -- loop through each of the lines first
  11593.           -- need to simply move to the next line...
  11594.           -- and columns_remaining_on_line could be as small as zero...
  11595.           if cursor_backward_line then
  11596.             -- ok, we moved one line forward
  11597.             number_to_move := number_to_move - columns_remaining_on_line 
  11598.                                              - 1 ;
  11599.               -- the minus one above is for the movement past the last 
  11600.               -- character on the line 
  11601.             left_and_right_columns(master_buffer,
  11602.                                    left_most_column,right_most_column);
  11603.             master_buffer.fixed_cursor.column_offset := right_most_column ;
  11604.             columns_remaining_on_line := right_most_column - left_most_column;
  11605.           else
  11606.             -- we were unable to move any further
  11607.             to_beginning ; -- so simply move to the end of the file
  11608.             number_to_move := 0 ;
  11609.           end if ;
  11610.         end loop ;
  11611.         if number_to_move > 0 then
  11612.           -- need to move within the current line
  11613.           master_buffer.fixed_cursor.column_offset :=
  11614.                 master_buffer.fixed_cursor.column_offset - number_to_move ;
  11615.         end if ;
  11616.       end if ;
  11617.       master_buffer.fixed_cursor.buffer_position := 0 ;
  11618.       if show_cursor_at_end then
  11619.         show_cursor ( master_buffer ) ;
  11620.       end if ;
  11621.     end move_horizontal ;
  11622.    
  11623.     Procedure MOVE_VERTICAL ( LINES_TO_MOVE_DOWN : in a_repeat_factor ;
  11624.                               show_cursor_at_end : in boolean := true ) is
  11625.       -- ***  bound cursor vertical movement / scroll if necessary *** --
  11626.       left_most_column ,
  11627.       right_most_column ,
  11628.       target_column : column_position ;
  11629.     begin -- move_vertical
  11630.       target_column := master_buffer.fixed_cursor.column_offset ;
  11631.       cursor_vertical( lines_to_move_down , false ) ;
  11632.       left_and_right_columns(master_buffer,left_most_column,right_most_column);
  11633.       if master_buffer.fixed_cursor.column_offset > right_most_column then
  11634.         master_buffer.fixed_cursor.column_offset := right_most_column ;
  11635.       elsif master_buffer.fixed_cursor.column_offset < left_most_column then
  11636.         master_buffer.fixed_cursor.column_offset := left_most_column ;
  11637.       end if ;
  11638.       master_buffer.fixed_cursor.buffer_position := 0 ;
  11639.       if show_cursor_at_end then
  11640.         show_cursor( master_buffer ) ;
  11641.       end if ;
  11642.     end move_vertical ;
  11643.      
  11644.     -- SAIC Editor Commands 
  11645.      
  11646.     function  find_forward ( pattern : in type_of_pattern ;
  11647.                              number_to_find : in a_repeat_factor := 1 
  11648.                              ) return text_position is
  11649.       still_to_do : a_repeat_factor := number_to_find ;
  11650.       old_cursor  : cursor_position ;
  11651.       cc          : character       ;
  11652.     begin -- find_forward 
  11653.       while still_to_do > 0 loop
  11654.         case pattern is 
  11655.           when word_pattern       => loop
  11656.                                        cc := char_at_position ;
  11657.                                      exit when not
  11658.                                          (   ((cc>='0') and (cc<='9'))
  11659.                                           or ((cc>='A') and (cc<='Z'))
  11660.                                           or ((cc>='a') and (cc<='z')) ) ;
  11661.                                        old_cursor := master_buffer.fixed_cursor;
  11662.                                        move_horizontal ( 1 , false ) ;
  11663.                                      exit when old_cursor = 
  11664.                                                  master_buffer.fixed_cursor ;
  11665.                                      end loop ;
  11666.                                      -- that moved past the current word
  11667.                                      -- now, move past trailing blanks.
  11668.                                      loop
  11669.                                        old_cursor := master_buffer.fixed_cursor;
  11670.                                        move_horizontal ( 1 , false ) ;
  11671.                                        cc := char_at_position ;
  11672.                                      exit when
  11673.                                          (   ((cc>='0') and (cc<='9'))
  11674.                                           or ((cc>='A') and (cc<='Z'))
  11675.                                           or ((cc>='a') and (cc<='z')) ) ;
  11676.                                      exit when old_cursor = 
  11677.                                                  master_buffer.fixed_cursor ;
  11678.                                      end loop ;
  11679.           when tab_pattern        => -- Need to move forward to the next
  11680.                                      -- tab position .
  11681.                                      -- master_buffer.pagezero.tabline
  11682.                                      --        ( column_position )
  11683.                                      --          = ( TNONE , TNORMAL , TNUMBER )
  11684.                                      -- we also know master_buffer.fixed_cursor.
  11685.                                      --                  column_offset
  11686.                                      loop
  11687.                                        old_cursor := master_buffer.fixed_cursor;
  11688.                                        move_horizontal( 1 , false ) ;
  11689.                                      exit when old_cursor = master_buffer.
  11690.                                                                  fixed_cursor 
  11691.                                        or else master_buffer.pagezero.tabline
  11692.                                                  ( master_buffer.fixed_cursor.
  11693.                                                      column_offset )
  11694.                                                /= tnone ;
  11695.                                      end loop ;
  11696.           when paragraph_pattern  => master_buffer.fixed_cursor.column_offset 
  11697.                                                                           := 0 ;
  11698.                                      move_vertical( 
  11699.                                        window_height(master_buffer) / 2 ,
  11700.                                        false ) ;
  11701.           when line_start_pattern => master_buffer.fixed_cursor.column_offset 
  11702.                                                                           := 0 ;
  11703.                                      move_vertical( still_to_do , false );
  11704.                                      still_to_do := 1 ; -- to stop loop 
  11705.           when line_end_pattern   => master_buffer.fixed_cursor.column_offset
  11706.                                                 := column_position'last ;
  11707.                                      move_vertical(still_to_do - 1 , false ) ;
  11708.                                      still_to_do := 1 ; -- to stop loop 
  11709.         end case ;
  11710.         still_to_do := still_to_do - 1;
  11711.       end loop ;
  11712.       return text_position ' ( master_buffer.fixed_cursor.file_line_number ,
  11713.                                master_buffer.fixed_cursor.column_offset    ,
  11714.                                no_screen_attribute                   ,
  11715.                                master_buffer                       ) ;
  11716.     end find_forward ;
  11717.      
  11718.     function find_backward ( pattern : in type_of_pattern ;
  11719.                              number_to_find : in a_repeat_factor := 1 
  11720.                              ) return text_position is
  11721.       still_to_do : a_repeat_factor := number_to_find ;
  11722.       old_cursor  : cursor_position ;
  11723.       cc          : character       ;
  11724.     begin -- find_backward
  11725.       while still_to_do > 0 loop
  11726.         case pattern is 
  11727.           when word_pattern       => loop
  11728.                                        old_cursor := master_buffer.fixed_cursor;
  11729.                                        move_horizontal ( -1 , false ) ;
  11730.                                        cc := char_at_position ;
  11731.                                      exit when 
  11732.                                          (   ((cc>='0') and (cc<='9'))
  11733.                                           or ((cc>='A') and (cc<='Z'))
  11734.                                           or ((cc>='a') and (cc<='z')) ) ;
  11735.                                      exit when old_cursor = 
  11736.                                                  master_buffer.fixed_cursor ;
  11737.                                      end loop ;
  11738.                                      -- that moved past the current word
  11739.                                      -- now, move past trailing blanks.
  11740.                                      loop
  11741.                                        old_cursor:= master_buffer.fixed_cursor ;
  11742.                                        move_horizontal ( -1 , false ) ;
  11743.                                        cc := char_at_position ;
  11744.                                      exit when not 
  11745.                                          (   ((cc>='0') and (cc<='9'))
  11746.                                           or ((cc>='A') and (cc<='Z'))
  11747.                                           or ((cc>='a') and (cc<='z')) ) ;
  11748.                                      exit when old_cursor = 
  11749.                                                  master_buffer.fixed_cursor ;
  11750.                                      end loop ;
  11751.                                      if old_cursor /= master_buffer
  11752.                                                               .fixed_cursor then
  11753.                                        move_horizontal( 1 , false ) ;
  11754.                                        -- to move to first char in word
  11755.                                      end if ;
  11756.           when tab_pattern        => -- Need to move forward to the next
  11757.                                      -- tab position .
  11758.                                      -- master_buffer.pagezero.tabline
  11759.                                      --        ( column_position )
  11760.                                      --          = ( TNONE , TNORMAL , TNUMBER )
  11761.                                      -- we also know master_buffer.fixed_cursor.
  11762.                                      --                  column_offset
  11763.                                      loop
  11764.                                        old_cursor:= master_buffer.fixed_cursor ;
  11765.                                        move_horizontal( -1 , false ) ;
  11766.                                      exit when old_cursor = master_buffer.
  11767.                                                                 fixed_cursor 
  11768.                                        or else master_buffer.pagezero.tabline
  11769.                                                  ( master_buffer.fixed_cursor.
  11770.                                                      column_offset )
  11771.                                                /= tnone ;
  11772.                                      end loop ;
  11773.           when paragraph_pattern  => move_vertical( 
  11774.                                        - window_height(master_buffer) / 2 ,
  11775.                                        false ) ;
  11776.           when line_start_pattern => master_buffer.fixed_cursor.column_offset 
  11777.                                                                           := 0 ;
  11778.                                      move_vertical( 1 - still_to_do , false );
  11779.                                      still_to_do := 1 ; -- to stop loop 
  11780.           when line_end_pattern   => master_buffer.fixed_cursor.column_offset
  11781.                                                 := column_position'last ;
  11782.                                      move_vertical(still_to_do , false ) ;
  11783.                                      still_to_do := 1 ; -- to stop loop 
  11784.         end case ;
  11785.         still_to_do := still_to_do - 1;
  11786.       end loop ;
  11787.       return text_position ' ( master_buffer.fixed_cursor.file_line_number ,
  11788.                                master_buffer.fixed_cursor.column_offset    ,
  11789.                                no_screen_attribute                   ,
  11790.                                master_buffer                       ) ;
  11791.     end ;
  11792.    
  11793.     Procedure position ( place : in text_position ;
  11794.                          show_cursor_at_end : boolean := true ) is
  11795.       -- move the cursor to the specified location.  Update the screen 
  11796.       -- unless requested otherwise
  11797.     begin -- position 
  11798.       if place = no_set_location then
  11799.         null ; -- can't do anything
  11800.       else
  11801.         if master_buffer.fixed_cursor.file_line_number /= place.line 
  11802.         or else master_buffer.fixed_cursor.column_offset /= place.column then
  11803.           -- we need to jump there
  11804.           jump_to_position ( master_buffer, place.line, place.column, false ) ;
  11805.         end if ;
  11806.       end if ;
  11807.       if show_cursor_at_end then
  11808.         show_cursor ( master_buffer ) ;
  11809.       end if ;
  11810.     end position ;
  11811.      
  11812.     procedure page_forward ( pages_to_move : a_repeat_factor ) is
  11813.       old_screen_line : window_line_number ;
  11814.       old_top         : line_number ;
  11815.     begin
  11816.       old_top := master_buffer.top_screen_cursor.file_line_number ;
  11817.       old_screen_line:=master_buffer.fixed_cursor.file_line_number + 1 -old_top;
  11818.       master_buffer.fixed_cursor.column_offset := 0 ;
  11819.       move_vertical( pages_to_move * window_height( master_buffer ) , false ) ;
  11820.       if old_top + window_height(master_buffer) - 1 
  11821.           < master_buffer.fixed_cursor.file_line_number then
  11822.         show_screen(master_buffer, master_buffer.fixed_cursor, old_screen_line);
  11823.       else
  11824.         show_cursor(master_buffer);
  11825.       end if ;
  11826.     end page_forward ;
  11827.      
  11828.     procedure page_backward ( pages_to_move : a_repeat_factor ) is
  11829.       old_screen_line : window_line_number ;
  11830.       old_top         : line_number ;
  11831.     begin
  11832.       old_top := master_buffer.top_screen_cursor.file_line_number ;
  11833.       old_screen_line:=master_buffer.fixed_cursor.file_line_number + 1 -old_top;
  11834.       master_buffer.fixed_cursor.column_offset := 0 ;
  11835.       move_vertical( - pages_to_move * window_height( master_buffer ), false ) ;
  11836.       if old_top /= 1 then
  11837.         -- because there can be no reason to move if the top of the screen
  11838.         -- didn't move....
  11839.         show_screen(master_buffer, master_buffer.fixed_cursor, old_screen_line);
  11840.       else
  11841.         show_cursor(master_buffer);
  11842.       end if ;
  11843.     end page_backward ;
  11844.      
  11845.     procedure move_to_home_position is
  11846.       old_position : text_position ;
  11847.     begin
  11848.       old_position := current_position ;
  11849.       jump_to_position( master_buffer , 
  11850.                 master_buffer.top_screen_cursor.file_line_number , 0 , false ) ;
  11851.       if old_position = current_position then
  11852.         -- we were already there...
  11853.         jump_to_position ( master_buffer , 
  11854.                            master_buffer.top_screen_cursor.file_line_number
  11855.                            + window_height(master_buffer) - 1 , 0 , false ) ;
  11856.       end if ;
  11857.       show_cursor( master_buffer ) ;
  11858.     end ;
  11859.        
  11860.     procedure move_to_zap_marker is
  11861.       old_position : text_position ;
  11862.     begin -- move_to_zap_marker 
  11863.       old_position := current_position ;
  11864.       position ( master_buffer.last_marked_position.data ) ;
  11865.       master_buffer.last_marked_position.data := old_position ;
  11866.     end move_to_zap_marker ;
  11867.      
  11868.     procedure do_move_command ( movement_command : in an_editor_command ;
  11869.                         repeat_factor     : in a_repeat_factor    ) is
  11870.       actual_command : an_editor_command := movement_command ;
  11871.       actual_repeat  : a_repeat_factor   := repeat_factor    ;
  11872.       current_column : column_position ;
  11873.       current_line   : line_number     ;
  11874.       current_pos    : text_position   ;
  11875.       Old_column : column_position ;
  11876.       Old_line   : line_number     ;
  11877.       old_pos    : text_position   ;
  11878.      
  11879.       procedure get_another_command is
  11880.       begin -- get_another_command ;
  11881.         get_next_command( actual_repeat , actual_repeat , actual_command ) ;
  11882.         case actual_command is
  11883.           when advance_character_command   
  11884.                  => if go_forward then
  11885.                       actual_command :=  forward_character_command ;
  11886.                     else
  11887.                       actual_command :=  backward_character_command ;
  11888.                     end if;
  11889.           when advance_word_command   
  11890.                  => if go_forward then
  11891.                       actual_command :=  forward_word_command ;
  11892.                     else
  11893.                       actual_command :=  backward_word_command ;
  11894.                     end if;
  11895.           when advance_tab_command   
  11896.                  => if go_forward then
  11897.                       actual_command :=  forward_tab_command ;
  11898.                     else
  11899.                       actual_command :=  backward_tab_command ;
  11900.                     end if;
  11901.           when advance_line_command   
  11902.                  => if go_forward then
  11903.                       actual_command :=  forward_line_command ;
  11904.                     else
  11905.                       actual_command :=  backward_line_command ;
  11906.                     end if;
  11907.           when advance_paragraph_command   
  11908.                  => if go_forward then
  11909.                       actual_command :=  forward_paragraph_command ;
  11910.                     else
  11911.                       actual_command :=  backward_paragraph_command ;
  11912.                     end if;
  11913.           when advance_page_command   
  11914.                  => if go_forward then
  11915.                       actual_command :=  forward_page_command ;
  11916.                     else
  11917.                       actual_command :=  backward_page_command ;
  11918.                     end if;
  11919.           when advance_infinity_command   
  11920.                  => if go_forward then
  11921.                       actual_command :=  jump_to_first_position_command ;
  11922.                     else
  11923.                       actual_command :=  jump_to_last_position_command ;
  11924.                     end if;
  11925.           when others => null ; 
  11926.         end case ;
  11927.       end get_another_command ;
  11928.        
  11929.     Procedure Cancell_A_Deletion( First_Pos,Second_Pos : in Text_Position ) is
  11930.       -- move between the two positions and reset the deletion flag to false
  11931.       -- redisplay the screen
  11932.     begin -- cancell_a_deletion
  11933.       null ;
  11934.     end cancell_a_deletion ;
  11935.       
  11936.     procedure do_delete_prompt is
  11937.     begin -- do_delete_prompt 
  11938.       set_repeat_prompt ( true , -1 ) ;
  11939.       if append_deletion then
  11940.         prompt( append_command_prompt ) ;
  11941.       else
  11942.         prompt(delete_command_prompt);
  11943.       end if ;
  11944.       need_prompt:=false;
  11945.       show_cursor( master_buffer ) ;
  11946.     end do_delete_prompt ;
  11947.      
  11948.     procedure start_deletion is
  11949.     begin -- start_deletion ;
  11950.       StrtDel_line   := current_buffer.fixed_cursor.file_line_number ;
  11951.       StrtDel_column := current_buffer.fixed_cursor.column_offset    ;
  11952.       StrtDel_Pos    := current_position ;
  11953.       allow_alternate_prompt_command := false ;
  11954.       do_delete_prompt ;
  11955.       get_another_command ;
  11956.     end start_deletion ;
  11957.      
  11958.     procedure work_deletion ( Old_Pos , New_Pos : in text_position ) is
  11959.       w_top_line      : line_number        ;
  11960.       w_bot_line      : line_number        ;
  11961.       w_left_column   : column_position    ;
  11962.       w_right_column  : column_position    ;
  11963.       orig_text       : type_text_line ; -- the original text line....
  11964.       First_Line : line_number     ;
  11965.       Last_Line  : line_number     ;
  11966.       First_Col  : column_position ;
  11967.       Last_Col   : integer         ;
  11968.       -- col2 is an integer because we do our own error checking.....
  11969.       win_line1  : window_line_number     ;
  11970.       win_col1   : window_column_number   ;
  11971.       win_line2  : window_line_number     ;
  11972.       win_col2   : window_column_number   ;
  11973.      
  11974.       Procedure Fix_Screen_Information is
  11975.         -- get screen information for comparison...
  11976.       begin -- fix_screen_information
  11977.         w_top_line      := master_buffer.top_screen_cursor.file_line_number ;
  11978.         w_bot_line      := w_top_line + window_height( master_buffer ) - 1  ;
  11979.         w_left_column   := lowest_column_number( master_buffer ) ;
  11980.         w_right_column  := highest_column_number( master_buffer ) ;
  11981.       end fix_screen_information ;
  11982.        
  11983.       function change_into_absolute_screen_locations return boolean is
  11984.       begin -- change_into_absolute_screen_locations
  11985.         -- here, we check values of the lines and also change to relative
  11986.         -- First Line...
  11987.         if First_Line > w_bot_line then
  11988.           -- off screen towards end, skip entire operation...
  11989.           return false ;
  11990.         elsif First_Line < w_top_line then
  11991.           -- the clear starts off the page towards front of file...
  11992.           win_line1 := 1 ;
  11993.           win_col1  := w_left_column ;
  11994.           first_line:= w_top_line    ;
  11995.           first_col := w_left_column ;
  11996.         else
  11997.           win_line1 := First_Line - w_top_line + 1 ;
  11998.           if first_col < w_left_column then
  11999.             win_col1  := w_left_column ;
  12000.             first_col := w_left_column ;
  12001.           else
  12002.             win_col1  := first_col ;
  12003.           end if ;
  12004.         end if ;
  12005.         -- Last Line...
  12006.         if Last_Line  < w_top_line then
  12007.           -- off screen towards front, skip entire operation
  12008.           return false ;
  12009.         elsif Last_Line  > w_bot_line then
  12010.           -- the clear ends off the page towards end of file
  12011.           win_line2 := window_height( master_buffer ) ;
  12012.           win_col2  := w_right_column + 1 ; -- because subtract later
  12013.           last_line := w_bot_line ;
  12014.           last_col  := w_right_column + 1 ;
  12015.         else
  12016.           win_line2 := Last_Line  - w_top_line + 1 ;
  12017.           if Last_Col   > w_right_column then
  12018.             win_col2 := w_right_column + 1 ;
  12019.             last_col := w_right_column + 1 ;
  12020.           else
  12021.             win_col2 := Last_Col   ;
  12022.           end if ;
  12023.         end if ;
  12024.         -- Now, adjust last columns....
  12025.         if win_col2 <= 1 then
  12026.           win_line2 := win_line2 - 1 ;
  12027.           last_line := last_line - 1 ;
  12028.           win_col2  := w_right_column ;
  12029.         else
  12030.           win_col2  := win_col2 - 1 ;
  12031.         end if ;
  12032.         last_col  := win_col2     ;
  12033.         return true ;
  12034.       end change_into_absolute_screen_locations ;
  12035.        
  12036.       procedure Clear    ( Left_Pos , Right_Pos : in text_position ) is
  12037.         -- Clear    starting at left_pos and up to and including the
  12038.         -- character before right_pos ... at least one char ...
  12039.       begin -- clear
  12040.         First_Line := Left_Pos.Line    ;
  12041.         Last_Line  := Right_Pos.Line   ;
  12042.         First_Col  := Left_Pos.Column  ;
  12043.         Last_Col   := Right_Pos.Column ;
  12044.         if change_into_absolute_screen_locations then
  12045.           -- win_line1,win_col1 to win_line2,win_col2 are to be cleared....
  12046.           -- first work line1 = line2 
  12047.           if win_line1 = win_line2 then
  12048.             -- just delete a few characters
  12049.             if win_col2 = w_right_column then
  12050.               clear_end_of_line( master_buffer , win_line1 , win_col1 ) ;
  12051.             else
  12052.               goto_line_column ( master_buffer , win_line1 , win_col1 ) ;
  12053.               for col in win_col1 .. win_col2 loop
  12054.                 put(' ');
  12055.               end loop ;
  12056.             end if ;
  12057.           else
  12058.             -- first do first line.
  12059.             if win_col1 <= w_right_column then
  12060.               clear_end_of_line( master_buffer , win_line1 , win_col1 ) ;
  12061.             end if ;
  12062.             -- then do middle lines
  12063.             for line_num in win_line1 + 1 .. win_line2 - 1 loop
  12064.               clear_end_of_line( master_buffer , line_num , w_left_column ) ;
  12065.             end loop ;
  12066.             -- then do last line ...
  12067.             if win_col2 >= w_left_column then
  12068.               if win_col2 = w_right_column then
  12069.                 clear_end_of_line( master_buffer , win_line2 , w_left_column ) ;
  12070.               else
  12071.                 goto_line_column ( master_buffer , win_line2 , w_left_column ) ;
  12072.                 for col in w_left_column .. win_col2 loop
  12073.                   put(' ');
  12074.                 end loop ;
  12075.               end if ;
  12076.             end if ;
  12077.           end if ;
  12078.         end if ;
  12079.       end clear ;
  12080.        
  12081.       procedure x_line_forward( which_buffer  : in out an_editor_buffer ) is
  12082.         ending_position : type_buffer_position ;
  12083.       begin -- x_line_forward 
  12084.         ending_position :=
  12085.                 which_buffer.fixed_cursor.line_start + line_length( 
  12086.                     which_buffer , which_buffer.fixed_cursor.line_start ) + 3 ;
  12087.         if which_buffer.e_buf(ending_position).data = buffer_boundry then
  12088.           which_buffer.moving_cursor := which_buffer.fixed_cursor ;
  12089.         else
  12090.           which_buffer.moving_cursor.line_start := ending_position ;
  12091.           which_buffer.moving_cursor.file_line_number :=
  12092.                   which_buffer.fixed_cursor.file_line_number + 1 ;
  12093.           which_buffer.moving_cursor.buffer_position := 0 ;
  12094.           which_buffer.moving_cursor.column_offset   := 0 ;
  12095.         end if;
  12096.       end x_line_forward ;
  12097.           
  12098.       procedure x_line_backward(which_buffer  : in out an_editor_buffer   ) is
  12099.         a_position      : type_buffer_position ;
  12100.       begin -- x_line_backward 
  12101.         a_position := which_buffer.fixed_cursor.line_start ;
  12102.         if which_buffer.e_buf(a_position - 1 ).data = buffer_boundry then
  12103.           which_buffer.moving_cursor := which_buffer.fixed_cursor ;
  12104.         else
  12105.           which_buffer.moving_cursor.line_start := a_position
  12106.                            - line_length( which_buffer , a_position-1 ) - 3 ;
  12107.           which_buffer.moving_cursor.file_line_number :=
  12108.                   which_buffer.fixed_cursor.file_line_number - 1 ;
  12109.           which_buffer.moving_cursor.buffer_position := 0 ;
  12110.           which_buffer.moving_cursor.column_offset   := 0 ;
  12111.         end if ;
  12112.       end x_line_backward ;
  12113.   
  12114.       procedure load_current_text ( to_line_number : line_number ) is
  12115.         -- get a line which is on the screen, which therefore is in memory,
  12116.         -- so no moving around is necessary....
  12117.         save_cursor : cursor_position ;
  12118.         line        : line_number     ;
  12119.       begin -- load_current_text
  12120.         save_cursor := master_buffer.fixed_cursor ;
  12121.         line   := master_buffer.fixed_cursor.file_line_number ;
  12122.         if to_line_number > line then
  12123.           -- We need to move forward 
  12124.           loop
  12125.             x_line_forward(master_buffer);
  12126.           exit when master_buffer.fixed_cursor = master_buffer.moving_cursor ; 
  12127.             -- end of file
  12128.             master_buffer.fixed_cursor := master_buffer.moving_cursor ;
  12129.             line   := line + 1   ;
  12130.           exit when line = to_line_number ; -- found line 
  12131.           end loop ;
  12132.           -- Here on either found line or at end of file
  12133.         elsif to_line_number < line then 
  12134.           -- We need to move backward 
  12135.           loop
  12136.             x_line_backward(master_buffer);
  12137.           exit when master_buffer.fixed_cursor = master_buffer.moving_cursor ; 
  12138.             -- end of file
  12139.             master_buffer.fixed_cursor := master_buffer.moving_cursor ;
  12140.             line   := line - 1   ;
  12141.           exit when line = to_line_number ; -- found line 
  12142.           end loop ;
  12143.           -- Here on either found line or at end of file
  12144.         end if ;
  12145.         -- Now, we need to move to the specified offset
  12146.         if line = to_line_number then
  12147.           get_text_line( master_buffer , master_buffer.fixed_cursor.line_start, 
  12148.                          orig_text ) ;
  12149.         else
  12150.           orig_text.data_length := 0 ;
  12151.         end if ;
  12152.         for posn in orig_text.data_length + 1 .. max_column_number loop
  12153.           orig_text.data(posn) := extended_character(32); -- spaces...
  12154.         end loop ;
  12155.         master_buffer.fixed_cursor := save_cursor ;
  12156.       end load_current_text ;
  12157.        
  12158.       procedure put ( c : extended_character ) is
  12159.       begin -- put
  12160.         put( character'val( c ) ) ;
  12161.       end put ;
  12162.        
  12163.       procedure Put_Back ( Left_Pos , Right_Pos : in text_position ) is
  12164.         -- put back starting at left_pos and up to and including the
  12165.         -- character before right_pos ... at least one char ...
  12166.         twindow_line : window_line_number ;
  12167.       begin -- put_back
  12168.         First_Line := Left_Pos.Line    ;
  12169.         Last_Line  := Right_Pos.Line   ;
  12170.         First_Col  := Left_Pos.Column  ;
  12171.         Last_Col   := Right_Pos.Column ;
  12172.         if change_into_absolute_screen_locations then
  12173.           -- win_line1,win_col1 to win_line2,win_col2 are to be put back...
  12174.           -- first work line1 = line2 
  12175.           if win_line1 = win_line2 then
  12176.             -- just put back a few characters
  12177.             -- just replace a few characters
  12178.             load_current_text ( first_line ) ;
  12179.             goto_line_column ( master_buffer , win_line1 , win_col1 ) ;
  12180.             for col in win_col1 .. win_col2 loop
  12181.               put( orig_text.data(col) );
  12182.             end loop ;
  12183.           else
  12184.             -- first do first line.
  12185.             if win_col1 <= w_right_column then
  12186.               load_current_text ( first_line ) ;
  12187.               goto_line_column ( master_buffer , win_line1 , win_col1 ) ;
  12188.               for col in win_col1 .. w_right_column loop
  12189.                 put( orig_text.data(col) ) ;
  12190.               end loop ;
  12191.             end if ;
  12192.             twindow_line := win_line1 ;
  12193.             -- then do middle lines
  12194.             for line_num in first_line + 1 .. last_line - 1 loop
  12195.               twindow_line := twindow_line + 1 ;
  12196.               load_current_text ( line_num ) ;
  12197.               goto_line_column( master_buffer , twindow_line , w_left_column ) ;
  12198.               for col in w_left_column .. w_right_column loop
  12199.                 put( orig_text.data(col) ) ;
  12200.               end loop ;
  12201.             end loop ;
  12202.             -- then do last line ...
  12203.             if win_col2 >= w_left_column then
  12204.               load_current_text ( last_line ) ;
  12205.               goto_line_column ( master_buffer , win_line2 , w_left_column ) ;
  12206.               for col in w_left_column .. win_col2 loop
  12207.                 put( orig_text.data(col) ) ;
  12208.               end loop ;
  12209.             end if ;
  12210.           end if ;
  12211.         end if ;
  12212.       end put_back ;
  12213.        
  12214.     begin -- work_deletion
  12215.       If Old_Pos /= New_Pos then
  12216.         -- we must do something...
  12217.         Fix_Screen_Information ;
  12218.         if StrtDel_Pos = New_Pos then
  12219.           -- we have moved back to the starting position
  12220.           If lt ( Old_Pos , StrtDel_Pos ) then
  12221.             -- we moved right last when moving back to the current position
  12222.             put_back ( Old_Pos , New_Pos ) ; -- puts back all but new_pos
  12223.           else
  12224.             -- we moved left last when moving back to current position
  12225.             put_back ( New_Pos , Old_Pos ) ; -- puts back all but Old_Pos 
  12226.           end if ;
  12227.         elsif lt ( StrtDel_Pos , New_Pos ) then
  12228.           -- we are deleting to the right of the starting position 
  12229.           if lt ( Old_Pos , StrtDel_Pos ) then
  12230.             -- we moved old .. start .. new 
  12231.             put_back ( Old_Pos , StrtDel_Pos ) ;
  12232.             Clear    ( StrtDel_Pos , New_Pos ) ;
  12233.           elsif lt ( Old_Pos , New_Pos ) then
  12234.             -- we are moving right to the right of the start position
  12235.             Clear    ( Old_Pos , New_Pos ) ;
  12236.           else
  12237.             -- we are moving left when to the right of the start position
  12238.             Put_Back ( New_Pos , Old_Pos ) ;
  12239.           end if ;
  12240.         else
  12241.           -- we are deleting to the left of the starting position
  12242.           if gt ( Old_Pos , StrtDel_Pos ) then
  12243.             -- we moved new .. start .. old
  12244.             put_back ( Old_Pos , StrtDel_Pos ) ;
  12245.             Clear    ( StrtDel_Pos , New_Pos ) ;
  12246.           elsif gt ( Old_Pos , New_Pos ) then
  12247.             -- we are moving left to the left of the start position
  12248.             Clear    ( New_Pos , Old_Pos ) ;
  12249.           else
  12250.             -- we are moving right when to the left of the start position
  12251.             Put_Back ( Old_Pos , New_Pos ) ;
  12252.           end if ;
  12253.         end if ;
  12254.         show_cursor ( master_buffer ) ;
  12255.       end if ;
  12256.     end work_deletion ;
  12257.      
  12258.     procedure end_deletion ( command : in an_editor_command ) is
  12259.       del_range : text_range ;
  12260.     begin -- end_deletion
  12261.       in_deletion := false ;
  12262.       allow_alternate_prompt_command := true ;
  12263.       need_prompt := true ;
  12264.       EndDelt_line   := current_buffer.fixed_cursor.file_line_number ;
  12265.       EndDelt_column := current_buffer.fixed_cursor.column_offset    ;
  12266.       EndDelt_Pos    := current_Position ;
  12267.       if StrtDel_Pos /= EndDelt_Pos then
  12268.         -- must do something
  12269.         del_range := text_range'( StrtDel_Pos         ,
  12270.                                   EndDelt_Pos         ,
  12271.                                   no_screen_attribute ) ;
  12272.         normalize_range( del_range ) ;
  12273.         -- if del_range.hi_position.column > 1 then
  12274.           -- stay on same line
  12275.           -- del_range.hi_position.column := del_range.hi_position.column - 1 ;
  12276.         -- else
  12277.           -- move to previous line
  12278.           -- del_range.hi_position.line := del_range.hi_position.line - 1 ;
  12279.           -- del_range.hi_position.column := max_column_number ;
  12280.         -- end if ;
  12281.         del_range.hi_position.column := del_range.hi_position.column - 1 ;
  12282.         Copy_Text_To_Copy_Buffer( master_buffer            , 
  12283.                                   del_range                ,
  12284.                                   append_deletion          ,
  12285.                                   command = accept_command ,
  12286.                                   command = accept_command ) ;
  12287.           -- copy the text within the range to the copy buffer
  12288.           -- then, delete the text......
  12289.         -- move the cursor to the correct position
  12290.         -- in any case, that is the starting position....
  12291.         --  ... because on accept, the ending text is moved to starting posn
  12292.         --  ...         on reject, we want to move to the beginning anyway
  12293.         -- jump_to_position ( master_buffer , del_range.lo_position.line    ,
  12294.                                            -- del_range.lo_position.column  , 
  12295.                                            -- false);
  12296.         -- now, update the screen as necessary
  12297.         if StrtDel_Line = EndDelt_Line then
  12298.           -- just show that line
  12299.           clear_line ( master_buffer ,
  12300.                        master_buffer.fixed_cursor.file_line_number 
  12301.                         - master_buffer.top_screen_cursor.file_line_number + 1);
  12302.           show_line ( master_buffer , 
  12303.                       master_buffer.fixed_cursor.line_start ,
  12304.                       master_buffer.fixed_cursor.file_line_number ) ;
  12305.         else
  12306.           -- redraw the entire screen 
  12307.           -- debugger.show_buffer ;
  12308.           show_screen ( master_buffer ,
  12309.                         master_buffer.fixed_cursor ,
  12310.                         0 ) ;
  12311.           -- debugger.show_buffer ;
  12312.         end if ;
  12313.       end if ;
  12314.     end end_deletion ;
  12315.      
  12316.     begin -- do_move_command
  12317.       -- note that we must come here with only those commands which are
  12318.       -- handled, otherwise, we will return the same command back and forth
  12319.       -- forever.....
  12320.       if actual_command = start_deletion_command then
  12321.         in_deletion := true ;
  12322.         append_deletion := false ;
  12323.         start_deletion ;
  12324.       else
  12325.         in_deletion := false ;
  12326.       end if ;
  12327.       current_column := current_buffer.fixed_cursor.file_line_number ;
  12328.       current_line   := current_buffer.fixed_cursor.column_offset    ;
  12329.       current_pos    := current_position ;
  12330.       loop
  12331.         if actual_repeat = infinity then
  12332.           -- we are moving to the beginning or end of the file 
  12333.           case actual_command is
  12334.             when up_command
  12335.                | left_command
  12336.                | backward_character_command 
  12337.                | backward_word_command 
  12338.                | backward_tab_command  
  12339.                | backward_line_command
  12340.                | backward_paragraph_command
  12341.                | backward_page_command 
  12342.                | jump_to_first_position_command => to_beginning ;
  12343.             when down_command
  12344.                | right_command
  12345.                | forward_character_command  
  12346.                | forward_word_command  
  12347.                | forward_tab_command   
  12348.                | forward_line_command
  12349.                | forward_paragraph_command
  12350.                | forward_page_command  
  12351.                | jump_to_last_position_command  => to_end       ;
  12352.             when home_command       => if in_deletion then
  12353.                                          append_deletion := not append_deletion;
  12354.                                          do_delete_prompt ;
  12355.                                        else
  12356.                                          move_to_home_position ;
  12357.                                        end if ;
  12358.             when jump_to_marked_position_command
  12359.                                     => move_to_zap_marker ;
  12360.             when accept_command     => if in_deletion then
  12361.                                          end_deletion( accept_command ) ;
  12362.                                        end if ;
  12363.             when reject_command     => if in_deletion then
  12364.                                          end_deletion( reject_command ) ;
  12365.                                        end if ;
  12366.             when set_forward_direction => go_forward := true ;
  12367.                                           set_direction ( go_forward ) ;
  12368.                                           show_cursor ;
  12369.                                           actual_command := illegal_command ;
  12370.             when set_backward_direction=> go_forward := false ;
  12371.                                           set_direction ( go_forward ) ;
  12372.                                           show_cursor ;
  12373.                                           actual_command := illegal_command ;
  12374.             when others             => -- we need to do something else....
  12375.                                        if in_deletion then -- can't leave
  12376.                                          crt_windows.bell ;
  12377.                                          actual_command := illegal_command ;
  12378.                                        else
  12379.                                          current_repeat_factor:= actual_repeat ;
  12380.                                          current_command := actual_command   ;
  12381.                                          return ;
  12382.                                        end if ;
  12383.               -- undefined for other commands such as home_command, 
  12384.               -- move_to_first_line...,  move_to_last_line_..., and
  12385.               -- all of the advance commands ( because the advance commands
  12386.               -- are mapped to a specific direction before we are called
  12387.           end case ;
  12388.          
  12389.         else 
  12390.          
  12391.           case actual_command is
  12392.             when up_command         => cursor_vertical  ( - actual_repeat ) ;
  12393.             when down_command       => cursor_vertical  (   actual_repeat ) ;
  12394.             when right_command      => cursor_horizontal(   actual_repeat ) ;
  12395.             when left_command       => cursor_horizontal( - actual_repeat ) ;
  12396.             when forward_character_command  
  12397.                                     => move_horizontal  (   actual_repeat ) ;
  12398.             when backward_character_command 
  12399.                                     => move_horizontal  ( - actual_repeat ) ;
  12400.             when forward_word_command  
  12401.                                     => position ( find_forward ( word_pattern  ,
  12402.                                                   actual_repeat           ) ) ;
  12403.             when backward_word_command 
  12404.                                     => position ( find_backward( word_pattern  ,
  12405.                                                   actual_repeat           ) ) ;
  12406.             when forward_tab_command   
  12407.                                     => position ( find_forward ( tab_pattern   ,
  12408.                                                   actual_repeat           ) ) ;
  12409.             when backward_tab_command  
  12410.                                     => position ( find_backward( tab_pattern   ,
  12411.                                                   actual_repeat           ) ) ;
  12412.             when forward_line_command
  12413.                                     => if actual_repeat = 0 then
  12414.                                          position ( find_backward (
  12415.                                                       line_start_pattern ) );
  12416.                                        else
  12417.                                          position ( find_forward ( 
  12418.                                                       line_start_pattern ,
  12419.                                                       actual_repeat       ) ) ;
  12420.                                        end if ;
  12421.                                        -- note that a zero repeat factor will
  12422.                                        -- force a call to find_backward...
  12423.             when backward_line_command
  12424.                                     => position ( find_backward ( 
  12425.                                                     line_start_pattern ,
  12426.                                                     actual_repeat + 1      ) ) ;
  12427.                                        -- note that a zero repeat factor moves
  12428.                                        -- to the start of the current line, 
  12429.                                        -- because it is the #1 line_start 
  12430.                                        -- found 
  12431.             when forward_paragraph_command
  12432.                                     => position ( find_forward ( 
  12433.                                                     paragraph_pattern ,
  12434.                                                   actual_repeat ) ) ;
  12435.             when backward_paragraph_command
  12436.                                     => position ( find_backward (
  12437.                                                     paragraph_pattern ,
  12438.                                                   actual_repeat ) ) ;
  12439.             when forward_page_command  
  12440.                                     => page_forward ( actual_repeat ) ;
  12441.             when backward_page_command 
  12442.                                     => page_backward ( actual_repeat ) ;
  12443.             when home_command       => if in_deletion then
  12444.                                          append_deletion := not append_deletion;
  12445.                                          do_delete_prompt ;
  12446.                                        else
  12447.                                          move_to_home_position ;
  12448.                                        end if ;
  12449.             when move_to_first_line_position_command 
  12450.                                     => position ( find_backward (
  12451.                                                     line_start_pattern , 1 ) ) ;
  12452.             when move_to_last_line_position_command  
  12453.                                     => position ( find_forward (
  12454.                                                     line_end_pattern , 1 ) ) ;
  12455.             when jump_to_first_position_command 
  12456.                                     => to_beginning ;
  12457.                                        show_cursor( master_buffer ) ;
  12458.             when jump_to_last_position_command  
  12459.                                     => to_end ;
  12460.                                        show_cursor( master_buffer ) ;
  12461.             when jump_to_marked_position_command
  12462.                                     => move_to_zap_marker ;
  12463.             when accept_command     => if in_deletion then
  12464.                                          end_deletion( accept_command ) ;
  12465.                                        end if ;
  12466.             when reject_command     => if in_deletion then
  12467.                                          end_deletion( reject_command ) ;
  12468.                                        end if ;
  12469.             when set_forward_direction => go_forward := true ;
  12470.                                           set_direction ( go_forward ) ;
  12471.                                           show_cursor ;
  12472.                                           actual_command := illegal_command ;
  12473.             when set_backward_direction=> go_forward := false ;
  12474.                                           set_direction ( go_forward ) ;
  12475.                                           show_cursor ;
  12476.                                           actual_command := illegal_command ;
  12477.             when others             => -- we need to do something else....
  12478.                                        if in_deletion then -- can't leave
  12479.                                          crt_windows.bell ;
  12480.                                          actual_command := illegal_command ;
  12481.                                        else
  12482.                                          current_repeat_factor:= actual_repeat ;
  12483.                                          current_command := actual_command   ;
  12484.                                          return ;
  12485.                                        end if ;
  12486.           end case;
  12487.         end if ;
  12488.         if actual_command /= illegal_command then
  12489.           Old_Column := Current_Column ;
  12490.           Old_Line   := Current_Line   ;
  12491.           Old_Pos    := Current_Pos    ;
  12492.           current_column := current_buffer.fixed_cursor.file_line_number ;
  12493.           current_line   := current_buffer.fixed_cursor.column_offset    ;
  12494.           Current_Pos    := Current_Position ;
  12495.           if in_deletion then
  12496.             work_deletion ( Old_Pos , Current_Pos ) ;
  12497.           end if ;
  12498.         end if ;
  12499.         get_another_command ;
  12500.       end loop ;
  12501.     end do_move_command ;
  12502.      
  12503.     procedure do_jump_command is
  12504.       new_location : text_position ;
  12505.     begin -- do_jump_command 
  12506.       set_prompt( master_buffer , 1 , jump_command_prompt ) ;
  12507.       case crt_windows.char_or_abort( ' ' , 'B' , 'E' , 'M' ) is 
  12508.         when 'B'       => to_beginning ;
  12509.                          show_cursor ( master_buffer ) ;
  12510.         when 'E'       => to_end       ;
  12511.                          show_cursor ( master_buffer ) ;
  12512.         when 'M'       => new_location := jump_to_marker ;
  12513.                           if new_location /= no_set_location then
  12514.                             position ( new_location ) ;
  12515.                           end if ;
  12516.         when others    => null ;
  12517.       end case ;
  12518.       need_prompt := true ; -- we need to reprompt after this...
  12519.     end do_jump_command ;
  12520.      
  12521.   begin -- movement_package
  12522.     -- MOVE     by SAIC/Clearwater Movement Package            25 Jan 84
  12523.     null ;
  12524.   end movement_package ;
  12525.  
  12526.   --$$$- MOVE
  12527.  
  12528. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  12529. --insert
  12530. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  12531.  
  12532.   --$$$+ INSERT
  12533.      
  12534.   --
  12535.   -- File 019
  12536.   --
  12537.   -- Editor Written By Robert S. Cymbalski
  12538.   --                   Science Applications International Corporation
  12539.   --                   Energy Systems Group
  12540.   --                   Ada Software Development Project Team
  12541.   --                   2280 U.S. Highway 19 North, Suite 120
  12542.   --                   Clearwater, Florida  33575
  12543.   --
  12544.   --
  12545.   -- Editor Revised from text Copyright (c) 1984 , R.S.Cymbalski
  12546.   -- 
  12547.         
  12548.   with string_library  ;
  12549.   use  string_library  ;
  12550.    
  12551.   with crt_customization ;
  12552.   use  crt_customization ;
  12553.   use  crt               ;
  12554.   use  editor_customization ;
  12555.    
  12556.   with crt_windows     ;
  12557.    
  12558.   with Wordp_Globals   ;
  12559.   use  Wordp_Globals   ;
  12560.  
  12561.   with editor_globals  ;
  12562.   use  editor_globals  ;
  12563.     
  12564.   with edit_windows    ;
  12565.   use  edit_windows    ;
  12566.     
  12567.   with markers         ;
  12568.     
  12569.   with buffer_package  ;
  12570.   use  buffer_package  ;
  12571.   use  buffer_general  ;
  12572.   use  buffer_lines    ;
  12573.     
  12574.   with editor_misc     ;
  12575.   use  editor_misc     ;
  12576.   use  copy_package    ;
  12577.    
  12578.   with debugger ;
  12579.   use  debugger ;
  12580.     
  12581.   with editor_even_more_packages ;
  12582.   use  editor_even_more_packages ;
  12583.    
  12584.   package insert_package is
  12585.      
  12586.     -- note that the left and paragraph margins are defined as the number
  12587.     -- of leading spaces that will appear before the first text character.  
  12588.     -- the right margin is defined as the position where the last valid
  12589.     -- character can go...
  12590.      
  12591.     procedure do_insert_command ;
  12592.        
  12593.   end;
  12594.      
  12595.   package body insert_package is
  12596.      
  12597.     procedure do_insert_command is
  12598.        
  12599.       -- where is the Insert cursor in the file ? 
  12600.       i_line_number   : line_number   ;
  12601.       i_column_number : column_position ;
  12602.       -- where is the Insert cursor on the screen ?
  12603.       w_line_number   : window_line_number ;
  12604.       -- what does the screen look like ? 
  12605.       w_top_line      : line_number        ;
  12606.       w_bot_line      : line_number        ;
  12607.       w_left_column   : column_position    ;
  12608.       w_right_column  : column_position    ;
  12609.       -- what is the text for the current line ? 
  12610.       txt             : type_text_line ;
  12611.       type type_old_end_of_line is 
  12612.              record
  12613.                data : pstring ; -- this is the actual text 
  12614.                data_leng : integer := 0 ; -- how long is it?
  12615.                put_in_col: integer := 0 ; -- what column to show it in 
  12616.                for_left_c: integer := 1 ; -- for what lowest column number
  12617.              end record ;
  12618.       old_end_of_line : type_old_end_of_line ;
  12619.       no_room_for_insert : exception ;
  12620.       moved_screen    : boolean := false ;
  12621.       on_first_line_of_insertion         : boolean ;
  12622.       first_line_first_valid_column      : column_position ;
  12623.       no_text_on_current_line            : boolean ;
  12624.       no_text_ever_on_current_line       : boolean ;
  12625.       show_old_line_end                  : boolean := true ;
  12626.       we_erased_rest_of_screen           : boolean := false ;
  12627.       old_line_is_at_end_of_current_line : boolean := false ;
  12628.       previous_line_start : type_buffer_position := 0 ;
  12629.       current_line_is_bobs_word_processing_command : boolean := false ;
  12630.        
  12631.       cursor_position_at_insert_entry : cursor_position ;
  12632.       cursor_position_at_insert_end   : cursor_position ;
  12633.       inserted_range : text_range ;
  12634.         
  12635.       insert_started_at_stuffstart       : boolean ;
  12636.       insert_ended_at_stuffstart         : boolean ;
  12637.       Old_Insert_Leading_Spaces          : type_leading_spaces ;
  12638.       in_numeric_tab  : boolean := false ;
  12639.      
  12640.       leading_spaces : type_leading_spaces ;
  12641.       first_text ,
  12642.       last_text  : type_text_length    ;
  12643.       ln_length  : type_line_length    ;
  12644.         
  12645.       orig_text       : type_text_line ;
  12646.        
  12647.       type type_numeric_info is
  12648.              record
  12649.                first_number_column: column_position ;
  12650.                -- first column where we can put a number for tab
  12651.                last_number_column : column_position ;
  12652.                -- last column where we can put a number for tab
  12653.                curr_number_column : column_position ;
  12654.                -- present column for number in numeric tab
  12655.                field_width        : column_position ;
  12656.                -- total number columns allowed in numeric tab
  12657.              end record ;
  12658.       numeric_info : type_numeric_info ;
  12659.         
  12660.       command_char    : character      ;
  12661.       editor_command  : editor_globals.an_editor_command ;
  12662.        
  12663.       a_space : constant extended_character 
  12664.                                 := extended_character(character'pos(' ') ) ;
  12665.        
  12666.       no_last_word_processor_key : constant string 
  12667.                      ( 1 .. max_wp_command_length ) := "                    "  ;
  12668.       last_word_processor_key : string ( 1 .. max_wp_command_length ) 
  12669.                                         := no_last_word_processor_key ;
  12670.       last_keystroke_was_return_on_non_wordp_command_line : boolean := false ;
  12671.       new_paragraph_key : constant string ( 1 .. max_wp_command_length ) 
  12672.                          := ascii.cr & ".new_paragraph" & ascii.cr & "    "  ;
  12673.       new_paragraph_key_length : constant integer := 16 ;
  12674.       add_one_line_key  : constant string ( 1 .. max_wp_command_length )
  12675.                          := ascii.cr & ".add 1" & ascii.cr & "            "  ;
  12676.       add_one_line_key_length : constant integer  := 8 ;
  12677.       last_key_not_a_word_processor_command : boolean := true ;
  12678.           
  12679.       procedure set_window_positions is
  12680.         -- we need to set the values that tell us where the window is
  12681.       begin
  12682.         w_top_line      := master_buffer.top_screen_cursor.file_line_number ;
  12683.         w_bot_line      := w_top_line + window_height( master_buffer ) - 1  ;
  12684.         w_left_column   := lowest_column_number( master_buffer ) ;
  12685.         w_right_column  := highest_column_number( master_buffer ) ;
  12686.         -- fix up the old end of line position information...
  12687.         old_end_of_line.put_in_col := old_end_of_line.put_in_col 
  12688.                - old_end_of_line.for_left_c + w_left_column ; 
  12689.         old_end_of_line.for_left_c := w_left_column ;
  12690.       end;
  12691.          
  12692.       procedure scroll_forward_a_line is
  12693.       begin -- scroll_forward_a_line
  12694.         w_top_line := w_top_line + 1 ;
  12695.         w_bot_line := w_bot_line + 1 ;
  12696.         -- now, to fix top and nxt cursors
  12697.         set_cursor_down_lines(master_buffer ,
  12698.                               master_buffer.top_screen_cursor ,
  12699.                               master_buffer.top_screen_cursor , 1 ) ;
  12700.         scroll_up_entire_window(1);
  12701.       end scroll_forward_a_line ;
  12702.        
  12703.       procedure load_current_text is
  12704.       begin -- load_current_text
  12705.         get_text_line( master_buffer , 
  12706.                        master_buffer.fixed_cursor.line_start , txt ) ;
  12707.         for posn in txt.data_length + 1 .. max_column_number loop
  12708.           txt.data(posn) := a_space; -- spaces...
  12709.         end loop ;
  12710.       end load_current_text ;
  12711.        
  12712.       procedure out_end_of_line( line : window_line_number ) is
  12713.         -- show the end of the first line....
  12714.       begin -- out_end_of_line
  12715.         -- only get here after checking that length is positive
  12716.         goto_line_column( master_buffer, line , old_end_of_line.put_in_col );
  12717.         put( old_end_of_line.data ) ;
  12718.       end out_end_of_line ;
  12719.         
  12720.       procedure initialize_Insert is
  12721.         -- used to be init_insertit
  12722.         nxt_line_start : type_buffer_position ;
  12723.         
  12724.         procedure set_old_line is
  12725.           break_char     : type_text_length    ;
  12726.         begin -- set_old_line 
  12727.           get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  12728.           old_insert_leading_spaces := leading_spaces ;
  12729.           if ln_length < 1 then
  12730.             break_char := i_column_number ;
  12731.           elsif i_column_number <= first_text then
  12732.             break_char := first_text ;
  12733.           else
  12734.             break_char := i_column_number ;
  12735.           end if ;
  12736.           old_end_of_line.data_leng := txt.data_length - break_char + 1 ;
  12737.           if old_end_of_line.data_leng > 0 then
  12738.             if old_end_of_line.data_leng > 
  12739.                         highest_column_number(master_buffer)
  12740.                           - lowest_column_number(master_buffer) + 1 then 
  12741.               old_end_of_line.data_leng := highest_column_number(master_buffer)
  12742.                                          - lowest_column_number(master_buffer) ;
  12743.               -- the above gives it up to width - 1 characters long, so it
  12744.               -- starts in column 2 on the display
  12745.             end if ;
  12746.             for posn in 1 .. old_end_of_line.data_leng loop
  12747.               old_end_of_line.data.data(posn) 
  12748.                 := character'val( txt.data( break_char + posn - 1 ) ) ; 
  12749.             end loop ;
  12750.             set_length( old_end_of_line.data , old_end_of_line.data_leng ) ;
  12751.             old_end_of_line.put_in_col := highest_column_number(master_buffer)
  12752.                                               - old_end_of_line.data_leng + 1 ;
  12753.             old_end_of_line.for_left_c := lowest_column_number(master_buffer);
  12754.           end if ;
  12755.           show_old_line_end := old_end_of_line.data_leng > 0 ;
  12756.         end set_old_line ;
  12757.           
  12758.       begin -- initialize_Insert 
  12759.         set_window_positions ;
  12760.         -- where is the Insert cursor in the file ? 
  12761.         i_line_number   := master_buffer.fixed_cursor.file_line_number ;
  12762.         i_column_number := master_buffer.fixed_cursor.column_offset    ;
  12763.         if i_column_number < 1 then
  12764.           i_column_number := 1 ;
  12765.         end if ;
  12766.         -- where is the Insert cursor on the screen ?
  12767.         w_line_number   := i_line_number - w_top_line + 1 ;
  12768.         set_repeat_prompt( false , 0 ) ;
  12769.         prompt( Insert_command_prompt ) ;
  12770.         show_cursor( master_buffer ) ;
  12771.         cursor_position_at_insert_entry := master_buffer.fixed_cursor ;
  12772.         load_current_text ;
  12773.         orig_text := txt ;
  12774.         -- now, work on buffer
  12775.         get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  12776.         nxt_line_start := master_buffer.fixed_cursor.line_start 
  12777.                           + ln_length + 3 ;
  12778.         open_buffer( master_buffer , nxt_line_start, max_bytes_in_line * 10 ) ;
  12779.         -- and delete current line...
  12780.         master_buffer.first_open_position 
  12781.                := master_buffer.fixed_cursor.line_start ;
  12782.         -- finish with current line
  12783.         no_text_on_current_line := ( ln_length = 0 ) 
  12784.                                 or ( i_column_number <= first_text ) ;
  12785.         no_text_ever_on_current_line := no_text_on_current_line ;
  12786.         insert_started_at_stuffstart := no_text_on_current_line ;
  12787.         -- now, we need to set up the old_end_of_line ;
  12788.         set_old_line ;
  12789.         -- now, we're ready...
  12790.         -- clear the remaining portion of the line
  12791.         for posn in i_column_number .. max_column_number loop
  12792.           txt.data(posn) := a_space; -- spaces...
  12793.         end loop ;
  12794.         clear_end_of_line ( master_buffer , w_line_number , i_column_number );
  12795.         if show_old_line_end then
  12796.           if old_end_of_line.put_in_col > i_column_number then
  12797.             old_line_is_at_end_of_current_line := true ;
  12798.             out_end_of_line( w_line_number ) ;
  12799.             goto_line_column(master_buffer, w_line_number , i_column_number);
  12800.           else
  12801.             -- it does not fit on the current line...
  12802.             old_line_is_at_end_of_current_line := false ;
  12803.             we_erased_rest_of_screen := true ;
  12804.             clear_end_of_screen( master_buffer ,
  12805.                                  w_line_number , i_column_number ) ;
  12806.             if w_line_number = window_height(master_buffer) - 1 then
  12807.               -- must scroll page
  12808.               scroll_forward_a_line ;
  12809.               w_line_number := window_height(master_buffer) - 1 ;
  12810.             end if ;
  12811.             out_end_of_line( w_line_number + 1 ) ;
  12812.             goto_line_column(master_buffer, w_line_number , i_column_number);
  12813.           end if ;
  12814.         end if ;
  12815.         on_first_line_of_insertion         := true ;
  12816.         if no_text_on_current_line then
  12817.           first_line_first_valid_column := 1 ;
  12818.         else
  12819.           first_line_first_valid_column := i_column_number ;
  12820.         end if ;
  12821.       end initialize_Insert ;
  12822.          
  12823.       procedure replace_current_text is
  12824.         leading    : type_leading_spaces ;
  12825.         text_first ,
  12826.         text_last  : type_text_length    ;
  12827.         text_leng  : type_line_length    ;
  12828.         ln_start   : type_buffer_position ;
  12829.         new_nxt_line : type_buffer_position ;
  12830.         successfull  : boolean ;
  12831.       begin -- replace_current_text 
  12832.         -- Then, reset the length and the leading spaces ...
  12833.         -- i_column_number - 1 is the highest column number worked with... 
  12834.         get_leading ( txt , leading , text_first , text_last , text_leng ) ;
  12835.         ln_start := master_buffer.fixed_cursor.line_start ;
  12836.         -- now, we need to move this line into the buffer....
  12837.         -- Four steps,  1: Open or close Buffer by appropriate positions
  12838.         -- must make sure we have room in buffer...
  12839.         if ln_start+max_bytes_in_line*2 > master_buffer.last_open_position then
  12840.           -- we need to make more room
  12841.           master_buffer.first_open_position 
  12842.                       := master_buffer.fixed_cursor.line_start ;
  12843.           -- we must push one block...
  12844.           if ln_start > block_size then
  12845.             push_data( master_buffer , thetop , successfull ) ;
  12846.           else
  12847.             push_data( master_buffer , thebot , successfull ) ;
  12848.           end if ;
  12849.           if not successfull then
  12850.             error( "Unable to update line. No Temporary File Room.",
  12851.                    not_fatal_error , operator_wait , short_beep ) ;
  12852.             return ; -- unable to update ...
  12853.           else
  12854.             master_buffer.fixed_cursor.line_start 
  12855.                   := master_buffer.first_open_position ;
  12856.             ln_start := master_buffer.fixed_cursor.line_start ;
  12857.           end if ;
  12858.         end if ;
  12859.         new_nxt_line := ln_start + text_leng + 3 ;
  12860.         master_buffer.first_open_position  := new_nxt_line ;
  12861.         --              3: Add the new line
  12862.         master_buffer.e_buf(ln_start).data    
  12863.                                 := extended_character(text_leng) ;
  12864.         master_buffer.e_buf(ln_start+1 ).data 
  12865.                                 := extended_character(leading) ;
  12866.         for place in 1 .. text_leng loop
  12867.           master_buffer.e_buf(ln_start + 1 + place ).data :=
  12868.                         txt.data(text_first+place-1) ;
  12869.         end loop ;
  12870.         master_buffer.e_buf(ln_start + text_leng + 2 ).data 
  12871.                                 := extended_character(text_leng) ;
  12872.         for place in ln_start .. ln_start + text_leng + 2 loop
  12873.           master_buffer.e_buf(place).attr := no_screen_attribute ;
  12874.         end loop ;
  12875.         master_buffer.fixed_cursor.line_start := new_nxt_line ;
  12876.         master_buffer.fixed_cursor.buffer_position := 0 ;
  12877.         master_buffer.fixed_cursor.file_line_number 
  12878.                := master_buffer.fixed_cursor.file_line_number + 1 ;
  12879.         --
  12880.         previous_line_start := ln_start ;  -- don't forget where it was set
  12881.         -- Initialize a new blank line....
  12882.         ln_start := new_nxt_line ;
  12883.         for posn in ln_start .. ln_start + 2 loop
  12884.           master_buffer.e_buf( posn ).data := extended_character( 0 ) ;
  12885.           master_buffer.e_buf( posn ).attr := no_screen_attribute     ;
  12886.         end loop ;
  12887.         master_buffer.e_buf( ln_start + 3 ).data 
  12888.                         := extended_character( buffer_boundry ) ;
  12889.         load_current_text ;
  12890.         no_text_on_current_line := true ;
  12891.         no_text_ever_on_current_line := true ;
  12892.         on_first_line_of_insertion   := false ;
  12893.         in_numeric_tab := false ; -- not yet processing a numeric tab 
  12894.         i_line_number := i_line_number + 1 ;
  12895.         current_line_is_bobs_word_processing_command := false ;
  12896.       end replace_current_text ;
  12897.          
  12898.       function to_text_pos ( curs : cursor_position ) return text_position is
  12899.       begin -- to_text_pos
  12900.         return text_position'( curs.file_line_number ,
  12901.                                curs.column_offset    ,
  12902.                                no_screen_attribute   ,
  12903.                                master_buffer       ) ;
  12904.       end to_text_pos ;
  12905.        
  12906.       procedure finish_insert( Last_Command : an_editor_command ) is
  12907.          
  12908.         procedure merge_last_line is
  12909.           posn : type_text_length ;
  12910.           offs : integer          ;
  12911.           leading_spaces  : type_leading_spaces ;
  12912.           first_text ,
  12913.           last_text  : type_text_length    ;
  12914.           ln_length  : type_line_length    ;
  12915.         begin -- merge_last_line 
  12916.           if old_end_of_line.data_leng > 0 then
  12917.             posn := i_column_number - 1 ;
  12918.             offs := 0 ;
  12919.             loop
  12920.             exit when posn = type_text_length'last ;
  12921.             exit when offs >= length( old_end_of_line.data ) ;
  12922.               posn := posn + 1 ;
  12923.               offs := offs + 1 ;
  12924.               txt.data(posn) := extended_character(
  12925.                                 character'pos(old_end_of_line.data.data(offs)));
  12926.             end loop ;
  12927.             txt.data_length := posn ;
  12928.           end if ;
  12929.           -- that merged the current line and end of start line 
  12930.           get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  12931.           replace_current_text ;
  12932.           -- now, set first open position
  12933.           master_buffer.first_open_position 
  12934.                       := master_buffer.fixed_cursor.line_start ;
  12935.           -- now, we may need to adjust the old information
  12936.           master_buffer.fixed_cursor.line_start := previous_line_start ;
  12937.           master_buffer.fixed_cursor.buffer_position := 0 ;
  12938.           master_buffer.fixed_cursor.file_line_number 
  12939.                  := master_buffer.fixed_cursor.file_line_number - 1 ;
  12940.           master_buffer.fixed_cursor.column_offset := i_column_number ;
  12941.           --
  12942.           cursor_position_at_insert_end := master_buffer.fixed_cursor ;
  12943.           insert_ended_at_stuffstart := ( ln_length = 0 ) 
  12944.                                      or ( i_column_number <= first_text ) ;
  12945.         end merge_last_line ;
  12946.          
  12947.         procedure adjust_leading ( new_leading : type_leading_spaces ) is
  12948.         begin -- adjust_leading
  12949.           master_buffer.e_buf( master_buffer.fixed_cursor.line_start + 1 )
  12950.                                .data := extended_character( new_leading ) ;
  12951.           cursor_position_at_insert_end.column_offset := new_leading + 1 ;
  12952.           master_buffer.fixed_cursor.column_offset    := new_leading + 1 ;
  12953.         end adjust_leading ;
  12954.          
  12955.         procedure just_show_screen( which_buffer : in out an_editor_buffer ;
  12956.                                     first_cursor : in cursor_position      ;
  12957.                                     last_line_num: in line_number          ) is
  12958.                    -- show from first cursor's line to last_line_num
  12959.           starting_position : type_buffer_position ;
  12960.           current_window_line ,
  12961.           last_window_line    : window_line_number ;
  12962.           current_line_number : line_number ;
  12963.           clear_each_line     : boolean  ;
  12964.         begin -- just_show_screen 
  12965.           which_buffer.floating_cursor := which_buffer.fixed_cursor ;
  12966.           which_buffer.fixed_cursor    := first_cursor ;
  12967.           current_line_number          := first_cursor.file_line_number ;
  12968.           current_window_line := current_line_number + 1 
  12969.                              - which_buffer.top_screen_cursor.file_line_number ;
  12970.           last_window_line    := last_line_num + 1 
  12971.                              - which_buffer.top_screen_cursor.file_line_number ;
  12972.           clear_each_line := last_window_line /= window_height(which_buffer);
  12973.           if not clear_each_line then
  12974.             clear_end_of_screen( which_buffer , current_window_line ,
  12975.                                      lowest_column_number( which_buffer ) ) ;
  12976.           end if ;
  12977.           loop
  12978.             if clear_each_line then
  12979.               clear_end_of_line( which_buffer , current_window_line ,
  12980.                                        lowest_column_number( which_buffer ) ) ;
  12981.             end if ;
  12982.             starting_position := which_buffer.fixed_cursor.line_start ;
  12983.             show_line( which_buffer, starting_position , current_line_number ) ;
  12984.             line_forward( which_buffer );
  12985.           exit when which_buffer.fixed_cursor = which_buffer.moving_cursor ;
  12986.             which_buffer.fixed_cursor := which_buffer.moving_cursor ;
  12987.             current_line_number := current_line_number + 1 ;
  12988.             current_window_line := current_window_line + 1 ;
  12989.           exit when ( current_window_line > last_window_line )  ;
  12990.           end loop ;
  12991.           which_buffer.fixed_cursor := which_buffer.floating_cursor ;
  12992.         end just_show_screen ;
  12993.         
  12994.         procedure reshow_line is
  12995.           -- for a reject command 
  12996.         begin -- reshow_line ;
  12997.           clear_end_of_line(master_buffer , w_line_number , w_left_column ) ;
  12998.           show_line ( master_buffer ,
  12999.                       master_buffer.fixed_cursor.line_start ,
  13000.                       master_buffer.fixed_cursor.file_line_number ) ; 
  13001.           show_cursor( master_buffer ) ;
  13002.         end reshow_line ;
  13003.        
  13004.       begin -- finish_insert
  13005.         -- cursor is at position i_column_number 
  13006.         txt.data_length := i_column_number - 1 ;
  13007.         merge_last_line ;
  13008.         close_buffer( master_buffer ) ;
  13009.         put_cursor_on_line( master_buffer , w_line_number ) ;
  13010.         -- to set top and next cursors
  13011.         -- When do we re-capture the leading blanks that we had when we
  13012.         -- started?  When the current line is empty, and we started at
  13013.         -- stuffstart (obviously).  Also,
  13014.        
  13015.         -- Old theory: Reject and started at stuffstart
  13016.         --          or No text on line and still on first line 
  13017.         --                              or autoindent
  13018.         --                              or filling off
  13019.         if last_command = reject_command then
  13020.           -- they ended with a reject
  13021.           If ( insert_started_at_stuffstart and insert_ended_at_stuffstart )
  13022.           and then cursor_position_at_insert_entry.file_line_number 
  13023.                  = cursor_position_at_insert_end.  file_line_number then
  13024.             -- put back orig now...
  13025.             adjust_leading( Old_Insert_Leading_Spaces ) ;
  13026.             cursor_position_at_insert_end := cursor_position_at_insert_entry ;
  13027.           else
  13028.             -- now, same as insert rules 
  13029.             if insert_ended_at_stuffstart 
  13030.             and then ( master_buffer.pagezero.filling 
  13031.                     or master_buffer.pagezero.autoindent ) then 
  13032.               adjust_leading( Old_Insert_Leading_Spaces ) ;
  13033.             end if ;
  13034.           end if ;
  13035.           Inserted_Range.Lo_Position := To_Text_Pos( 
  13036.                                              Cursor_position_at_insert_entry ) ;
  13037.           Inserted_Range.Hi_Position := To_Text_Pos( 
  13038.                                              Cursor_position_at_insert_end   ) ;
  13039.           If inserted_range.hi_position.column > 0 then
  13040.             inserted_range.hi_position.column 
  13041.               := inserted_range.hi_position.column - 1 ;
  13042.           end if ;
  13043.           copy_text_to_copy_buffer( master_buffer,inserted_range,
  13044.                                     false,      -- don't add to previous copy
  13045.                                     true ,      -- delete after copy
  13046.                                     false  ) ;  -- don't adjust cursors
  13047.           -- must set fixed cursor correctly 
  13048.           adjust_leading( Old_Insert_Leading_Spaces ) ;
  13049.           -- need to redisplay screen
  13050.           if we_erased_rest_of_screen then
  13051.             show_screen( master_buffer ) ;
  13052.           else
  13053.             reshow_line ;
  13054.           end if ;
  13055.         else
  13056.           -- they ended with an accept 
  13057.           if insert_ended_at_stuffstart 
  13058.           and then ( master_buffer.pagezero.filling 
  13059.                   or master_buffer.pagezero.autoindent ) then 
  13060.             adjust_leading( Old_Insert_Leading_Spaces ) ;
  13061.           end if ;
  13062.           Inserted_Range.Lo_Position := To_Text_Pos( 
  13063.                                              Cursor_position_at_insert_entry ) ;
  13064.           Inserted_Range.Hi_Position := To_Text_Pos( 
  13065.                                              Cursor_position_at_insert_end   ) ;
  13066.           If inserted_range.hi_position.column > 0 then
  13067.             inserted_range.hi_position.column 
  13068.               := inserted_range.hi_position.column - 1 ;
  13069.           end if ;
  13070.           copy_text_to_copy_buffer( master_buffer , inserted_range ,
  13071.                                     false ,     -- don't add to previous copy
  13072.                                     false ,     -- don't delete after copy
  13073.                                     true  ) ;   -- adjust cursors after adding
  13074.           -- now, check out filling...
  13075.           if master_buffer.pagezero.filling 
  13076.           and not master_buffer.pagezero.autoindent then 
  13077.             clear_window( master_buffer ) ;
  13078.             prompt(" Re-filling remaining portion of paragraph. ");
  13079.             do_re_margin_command( master_buffer.fixed_cursor , false ) ;
  13080.           else
  13081.             -- need to finish up this line only, if we still have the
  13082.             -- stuff on this line, otherwise, rest of screen
  13083.             if we_erased_rest_of_screen then
  13084.               -- need to show from this to end of screen
  13085.               just_show_screen( master_buffer ,
  13086.                                 cursor_position_at_insert_end ,
  13087.                       master_buffer.top_screen_cursor.file_line_number
  13088.                         + window_height(master_buffer) - 1 ) ;
  13089.             else
  13090.               -- need to show only this line
  13091.               just_show_screen( master_buffer ,
  13092.                                 cursor_position_at_insert_end ,
  13093.                                 cursor_position_at_insert_end.file_line_number);
  13094.             end if ;
  13095.           end if ;
  13096.         end if ;
  13097.         need_prompt := true ;
  13098.       end finish_insert ;
  13099.        
  13100.       procedure beep_the_bell is
  13101.       begin
  13102.         crt_windows.bell ;
  13103.       end ;
  13104.         
  13105.       procedure get_c_or_cmd( c  : out character                        ;
  13106.                               cmd: out editor_globals.an_editor_command ) is
  13107.           
  13108.         -- used to be xgetch....
  13109.           
  13110.         -- get either a printable character or else get an editor command...
  13111.         -- note that here, printable characters take priority over commands
  13112.         physical_c : character ;
  13113.         physical_command : crt.special_keys ;
  13114.       begin -- get_c_or_cmd
  13115.         crt_windows.key_input( physical_c , physical_command ) ;
  13116.         if physical_command = key_character 
  13117.         and then physical_c in ' ' .. '~' then
  13118.           -- easy... is just a printable character ...????
  13119.           c := physical_c ;
  13120.           cmd := editor_customization.illegal_command ;
  13121.           -- I really wanted to use editor_globals.illegal_command.......
  13122.         else
  13123.           -- need to find out what it might be...
  13124.           translate( physical_c , physical_command , c , cmd ) ;
  13125.         end if ;
  13126.       end get_c_or_cmd ;
  13127.        
  13128.       procedure pop_down_a_line_if_there_is_a_line_end is
  13129.       begin -- pop_down_a_line_if_there_is_a_line_end
  13130.         if show_old_line_end then
  13131.           if we_erased_rest_of_screen then
  13132.             -- just need to work on our next line then...
  13133.             clear_end_of_line( master_buffer, w_line_number, i_column_number );
  13134.           else
  13135.             -- we need to clear that entire screen...
  13136.             -- it does not fit on the current line...
  13137.             we_erased_rest_of_screen := true ;
  13138.             clear_end_of_screen( master_buffer,w_line_number, i_column_number );
  13139.           end if ;
  13140.           goto_line_column( master_buffer , w_line_number , w_left_column ) ;
  13141.           put(ascii.cr); -- to ensure that we have room for a new line 
  13142.           if w_line_number = window_height( master_buffer ) then
  13143.             w_line_number := w_line_number - 1 ;
  13144.           end if ;
  13145.           out_end_of_line( w_line_number + 1 ) ;
  13146.           goto_line_column(master_buffer, w_line_number , i_column_number);
  13147.         end if ;
  13148.         old_line_is_at_end_of_current_line := false ;
  13149.       end pop_down_a_line_if_there_is_a_line_end ;
  13150.        
  13151.       procedure redo_screen ( new_col : integer ) is
  13152.         first_col_to_do : integer ;
  13153.       begin -- redo_screen
  13154.         show_screen( master_buffer ) ;
  13155.         set_window_positions ;
  13156.         we_erased_rest_of_screen := true ;
  13157.         -- now, show the current line ...
  13158.         txt.data_length := i_column_number - 1 ;
  13159.         get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13160.         if ln_length > 0 then
  13161.           first_col_to_do := max( first_text , w_left_column ) ;
  13162.           goto_line_column( master_buffer , w_line_number , first_col_to_do );
  13163.           for posn in first_col_to_do .. last_text loop
  13164.             put( character'val( txt.data(posn) ) ) ;
  13165.           end loop ;
  13166.         end if ;
  13167.         -- then, old line end ...
  13168.         if show_old_line_end then
  13169.           out_end_of_line( w_line_number + 1 ) ;
  13170.         end if ;
  13171.         -- and position the cursor ...
  13172.         goto_line_column( master_buffer , w_line_number , new_col ) ;
  13173.       end redo_screen ;
  13174.        
  13175.       procedure make_pos_valid_on_screen_then_char_out
  13176.                               ( c : character ; how_many : integer ) is
  13177.         -- assume called AFTER the txt area is set with values...
  13178.         new_col : integer ;
  13179.       begin -- make_pos_valid_on_screen_then_char_out 
  13180.         new_col := i_column_number + how_many ;
  13181.         if new_col > w_right_column then
  13182.           -- we must shift and re-do the screen
  13183.           shift( master_buffer , - max( 15, new_col - w_right_column + 5 )) ;
  13184.           redo_screen ( new_col ) ;
  13185.         elsif new_col < w_left_column then
  13186.           -- must shift and re-do screen
  13187.           shift( master_buffer , 
  13188.             max( 15 , w_left_column - new_col + 5 ) ) ;
  13189.           redo_screen ( new_col ) ;
  13190.         else
  13191.           for posn in 1 .. how_many loop
  13192.             put( c ) ;
  13193.           end loop ;
  13194.         end if ;
  13195.         i_column_number := new_col ;
  13196.       end make_pos_valid_on_screen_then_char_out ;
  13197.      
  13198.       procedure start_next_line is
  13199.         next_line_blanks : integer ; -- because we must first check to see
  13200.                                      -- that it is in type_leading_spaces ;
  13201.       begin -- start_next_line 
  13202.         txt.data_length := i_column_number - 1 ;
  13203.         get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13204.         if master_buffer.pagezero.autoindent then
  13205.           next_line_blanks := leading_spaces ;
  13206.         elsif master_buffer.pagezero.filling then
  13207.           if ln_length < 1 or else txt.data(first_text) = 
  13208.                                    extended_character(character'pos(
  13209.                                      master_buffer.pagezero.break_char )) then
  13210.             next_line_blanks := master_buffer.pagezero.paramargin ;
  13211.           else
  13212.             next_line_blanks := master_buffer.pagezero.lmargin    ;
  13213.           end if ;
  13214.         else
  13215.           next_line_blanks := 0 ;
  13216.         end if ;
  13217.         if next_line_blanks > type_leading_spaces'last then
  13218.           next_line_blanks := type_leading_spaces'last ;
  13219.         end if ;
  13220.         if master_buffer.pagezero.justify then
  13221.           txt.data_length := i_column_number - 1 ;
  13222.           do_justify ( txt ) ;
  13223.           i_column_number := txt.data_length + 1 ;
  13224.         end if ;
  13225.         replace_current_text ; -- to save the new text
  13226.         if we_erased_rest_of_screen then
  13227.           if i_column_number < w_right_column then
  13228.             clear_end_of_line( master_buffer , w_line_number , i_column_number);
  13229.           end if ;
  13230.         else
  13231.           we_erased_rest_of_screen := true ;
  13232.           clear_end_of_screen( master_buffer , w_line_number , i_column_number);
  13233.         end if ;
  13234.         if w_line_number = window_height(master_buffer) then
  13235.           scroll_up_entire_screen(1);
  13236.         else
  13237.           w_line_number := w_line_number + 1 ;
  13238.         end if ;
  13239.         pop_down_a_line_if_there_is_a_line_end ;
  13240.         i_column_number := next_line_blanks + 1 ;
  13241.         make_pos_valid_on_screen_then_char_out( ' ' , 0 ) ;
  13242.         goto_line_column( master_buffer , w_line_number , i_column_number ) ;
  13243.       end start_next_line ;
  13244.         
  13245.       procedure pop_over_the_current_word is
  13246.         -- scan the line we are on.  Take the last word off.  
  13247.         -- move down to the next line.  Put the word in.
  13248.         posn      : integer ;
  13249.         type word_of_text is array ( type_line_length 
  13250.                                      range 1 .. max_line_length ) of
  13251.                                      extended_character ;
  13252.         new_word  : word_of_text ;
  13253.         new_word_length : integer ;
  13254.       begin -- pop_over_the_current_word
  13255.         txt.data_length := i_column_number - 1 ;
  13256.         get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13257.         -- look for ' ' or '-'
  13258.         posn := last_text ;
  13259.         -- find last non-blank
  13260.         loop
  13261.         exit when posn <= first_text ; -- don't do anything
  13262.         exit when txt.data(posn) /= a_space;
  13263.           posn := posn - 1 ;
  13264.         end loop ;
  13265.         if posn > first_text then
  13266.           -- ok, we have something to work on, a word on a multi word line
  13267.           -- find last '-' or ' ' 
  13268.           loop
  13269.           exit when posn <= first_text ; -- don't do anything
  13270.           exit when txt.data(posn) = a_space
  13271.           or else txt.data(posn) = extended_character( character'pos('-') ) ;
  13272.             posn := posn - 1 ;
  13273.           end loop ;
  13274.           if posn > first_text then
  13275.             -- ok, found it
  13276.             posn := posn + 1 ; -- move past item to stay on the line
  13277.             -- now, move posn .. last_text to next line....
  13278.             new_word_length := last_text - posn + 1 ;
  13279.             if new_word_length > type_line_length'last then
  13280.               -- error
  13281.               new_word_length := type_line_length'last ;
  13282.             end if ;
  13283.             if new_word_length >= w_right_column - w_left_column + 1 then
  13284.               -- error
  13285.               -- must be no greater than one char less than screen width
  13286.               new_word_length := w_right_column - w_left_column ;
  13287.             end if ;
  13288.             for move_char in 1 .. new_word_length loop
  13289.               new_word( move_char ) := txt.data( posn + move_char - 1 ) ;
  13290.             end loop ;
  13291.             txt.data_length := posn - 1 ; -- sets last char to stay on line
  13292.             i_column_number := posn ; -- for replace current text
  13293.             start_next_line ; -- erases extra, and everything...
  13294.             for move_char in 1 .. new_word_length loop
  13295.               put( character'val( new_word( move_char ) ) ) ;
  13296.               txt.data(i_column_number+move_char-1):=new_word(move_char);
  13297.             end loop ;
  13298.             i_column_number := i_column_number + new_word_length ;
  13299.             no_text_on_current_line := false ;
  13300.             no_text_ever_on_current_line := false ;
  13301.           end if ;
  13302.         end if ;
  13303.       end pop_over_the_current_word ;
  13304.        
  13305.       procedure do_char ( c : in character ) is 
  13306.       begin -- do_char
  13307.         if i_column_number < column_position'last then
  13308.           if i_column_number = 1 then
  13309.             -- special check just for bob's word processing command
  13310.             current_line_is_bobs_word_processing_command := c = '.' ;
  13311.           end if ;
  13312.           if c /= ' ' then
  13313.             no_text_on_current_line := false ;
  13314.             no_text_ever_on_current_line := false ;
  13315.           end if ;
  13316.           if in_numeric_tab then
  13317.             -- must do special work
  13318.             -- note that we are guaranteed that the entire number is on the
  13319.             -- screen
  13320.             if c in '0' .. '9'
  13321.             or else c = '-'
  13322.             or else c = '+'
  13323.             or else c = ','
  13324.             or else c = '$'
  13325.             or else c = '(' then
  13326.               -- valid numeric tab item 
  13327.               if numeric_info.first_number_column 
  13328.                < numeric_info.curr_number_column then 
  13329.                 -- there is room for at least one number to float ...
  13330.                 numeric_info.curr_number_column 
  13331.                             := numeric_info.curr_number_column - 1 ;
  13332.                 goto_line_column ( master_buffer , w_line_number ,
  13333.                                    numeric_info.first_number_column ) ;
  13334.                 for posn in numeric_info.curr_number_column ..
  13335.                             numeric_info.last_number_column - 1 loop 
  13336.                   txt.data(posn) := txt.data(posn+1) ;
  13337.                   put( character'val( txt.data(posn) ) ) ;
  13338.                 end loop ;
  13339.                 i_column_number := i_column_number - 1 ;
  13340.               else
  13341.                 in_numeric_tab := false ;
  13342.               end if ;
  13343.             else
  13344.               in_numeric_tab := false ;
  13345.             end if ;
  13346.           -- else no need to do special work...
  13347.           end if ;
  13348.           txt.data(i_column_number) := extended_character( character'pos(c) );
  13349.           make_pos_valid_on_screen_then_char_out( c , 1 ) ;
  13350.           if master_buffer.pagezero.filling then
  13351.             -- these are the special considerations for filling on
  13352.             if c /= ' ' then 
  13353.               if i_column_number > master_buffer.pagezero.rmargin + 1 then
  13354.                 -- special work for filling when we hit the end of the line
  13355.                 pop_over_the_current_word ;
  13356.               end if ;
  13357.             elsif i_column_number > master_buffer.pagezero.rmargin + 11 then
  13358.               -- only do spaces if we are 10 spaces past end
  13359.               pop_over_the_current_word ;
  13360.             end if ;
  13361.           else
  13362.             -- these are the special considerations for filling off
  13363.             null ;
  13364.           end if ;
  13365.           if old_line_is_at_end_of_current_line 
  13366.           and then show_old_line_end 
  13367.           and then i_column_number + 1 >= old_end_of_line.put_in_col then
  13368.             pop_down_a_line_if_there_is_a_line_end ;
  13369.           end if ;
  13370.         end if ;
  13371.       end do_char ;
  13372.          
  13373.       procedure do_a_tab is
  13374.         old_col : integer  ;
  13375.         new_col : integer ;
  13376.         new_tab : tabtypes ; -- type TABTYPES is ( TNONE , TNORMAL , TNUMBER ); 
  13377.       begin -- do_a_tab
  13378.         -- Need to move forward to the next tab position .
  13379.         old_col := i_column_number ;
  13380.         new_col := i_column_number ;
  13381.         loop
  13382.         exit when new_col >= column_position'last ;
  13383.         -- don't allow tab past last position 
  13384.           new_col := new_col + 1 ;
  13385.           new_tab := master_buffer.pagezero.tabline ( new_col ) ;
  13386.         exit when new_tab /= tnone ;
  13387.         end loop ;
  13388.         -- ok, we have i_column_number as old and new_col as new
  13389.         if new_col > i_column_number then
  13390.           if new_tab = tnone then
  13391.             -- no more tabs on line...
  13392.             beep_the_bell ;
  13393.           else
  13394.             in_numeric_tab:= master_buffer.pagezero.tabline(new_col) = tnumber ;
  13395.             for posn in i_column_number .. new_col - 1 loop
  13396.               txt.data(posn) := a_space ;
  13397.             end loop ;
  13398.             if old_line_is_at_end_of_current_line 
  13399.             and then show_old_line_end 
  13400.             and then new_col+ 1 >= old_end_of_line.put_in_col then
  13401.               pop_down_a_line_if_there_is_a_line_end ;
  13402.             end if ;
  13403.             make_pos_valid_on_screen_then_char_out
  13404.                                     ( ' ' , new_col - i_column_number ) ;
  13405.             if in_numeric_tab then
  13406.               -- must set some information....
  13407.               -- don't let the witdth be more that 1/2 screen
  13408.               if ( new_col - old_col ) * 2 > w_right_column - w_left_column then
  13409.                old_col := new_col - ( w_right_column - w_left_column ) / 2 ;
  13410.               end if;
  13411.               numeric_info.first_number_column:= old_col + 1         ;
  13412.               numeric_info.last_number_column := i_column_number - 1 ;
  13413.               numeric_info.curr_number_column := i_column_number ;
  13414.               numeric_info.field_width        := i_column_number - old_col - 1 ;
  13415.             end if ;
  13416.           end if ;
  13417.         end if ;
  13418.       end do_a_tab ;
  13419.         
  13420.       procedure insert_word_processor_command( new_command : string ;
  13421.                                                use_length  : integer ) is
  13422.         -- insert this new word processor command string into the 
  13423.         -- buffer .....
  13424.         -- The string of characters associated with the function key hit
  13425.         -- If the first character is ascii.cr, then start a new line at
  13426.         -- column 1.  If the length is greater than 1 and then the last 
  13427.         -- character is ascii.cr, then end by starting a new line and 
  13428.         -- indenting to the old indentation from before the command key.
  13429.         -- If the first character is a space, then, only put the space in
  13430.         -- if the last character was not a space
  13431.         -- current_line_is_bobs_word_processing_command : boolean := false ;
  13432.         old_leading_spaces : type_leading_spaces ;
  13433.         next_position : integer := 1 ;
  13434.         next_char : character ;
  13435.       begin -- insert_word_processor_command
  13436.         last_key_not_a_word_processor_command := false ;
  13437.         last_word_processor_key := new_command ; 
  13438.         -- because in fact we are only called with a string of exactly the
  13439.         -- correct length
  13440.         txt.data_length := i_column_number - 1 ;
  13441.         get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13442.         old_leading_spaces := leading_spaces ;
  13443.         loop
  13444.           -- here, display the command until we hit end or else we hit 
  13445.           -- ascii.cr
  13446.           next_char := new_command( next_position ) ;
  13447.           if next_char = ascii.cr then
  13448.             -- we must move to start of a line 
  13449.             txt.data_length := i_column_number - 1 ;
  13450.             get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13451.             if ln_length > 0 then
  13452.               -- end the current line 
  13453.               start_next_line ;
  13454.             end if ;
  13455.             i_column_number := 1 ;
  13456.             make_pos_valid_on_screen_then_char_out ( ' ' , 0 ) ;
  13457.             goto_line_column( master_buffer , w_line_number , i_column_number );
  13458.           else
  13459.             if next_char = ' ' 
  13460.             and then next_position = 1 
  13461.             and then i_column_number > 1 
  13462.             and then txt.data( i_column_number - 1 ) = a_space then
  13463.               null ; -- skip it 
  13464.             else
  13465.               do_char( next_char ) ;
  13466.             end if ;
  13467.           end if ;
  13468.           next_position := next_position + 1 ;
  13469.         exit when next_position > use_length ;
  13470.         end loop ;
  13471.         txt.data_length := i_column_number - 1 ;
  13472.         get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13473.         -- finally, if no text on line, then put back old_leading_spaces 
  13474.         -- if required...
  13475.         if ln_length = 0 then
  13476.           if master_buffer.pagezero.autoindent then
  13477.             -- we must check to see if we should put back old blanks ...
  13478.             i_column_number := old_leading_spaces + 1 ;
  13479.           elsif master_buffer.pagezero.filling then
  13480.             -- must start a new paragraph...
  13481.             i_column_number := master_buffer.pagezero.paramargin + 1 ;
  13482.           end if ;
  13483.           txt.data_length := i_column_number - 1 ;
  13484.           for space_position in 1 .. txt.data_length loop
  13485.             txt.data( space_position ) := a_space ;
  13486.           end loop ;
  13487.         end if ;
  13488.         make_pos_valid_on_screen_then_char_out ( ' ' , 0 ) ;
  13489.         goto_line_column( master_buffer , w_line_number , i_column_number ) ;
  13490.       end insert_word_processor_command ;
  13491.        
  13492.       procedure backup_char ( cmd : editor_globals.an_editor_command ) is
  13493.         -- used to be backup and do_ctrl_w
  13494.         cc : character ;
  13495.        
  13496.         function char_at_position return character is
  13497.           -- return the character at the current cursor position 
  13498.         begin
  13499.           -- if on first line and we are left of starting position, return
  13500.           -- nul
  13501.           if on_first_line_of_insertion 
  13502.           and then i_column_number < first_line_first_valid_column then 
  13503.             return ascii.nul ;
  13504.           else
  13505.             return character'val ( txt.data( i_column_number ) ) ;
  13506.           end if ;
  13507.         end char_at_position ;
  13508.          
  13509.         procedure move_to_posn ( posn : integer ) is
  13510.           -- if possible, move to this column position 
  13511.           -- change i_column_number , screen's cursor
  13512.           -- check actual screen window boundries...
  13513.           moving_col : column_position ;
  13514.           target_col : column_position ;
  13515.         begin -- move_to_posn 
  13516.           moving_col := i_column_number ;
  13517.           if on_first_line_of_insertion 
  13518.           and then posn < first_line_first_valid_column then
  13519.             target_col := first_line_first_valid_column ;
  13520.             beep_the_bell ;
  13521.           else
  13522.             target_col := posn ;
  13523.           end if ;
  13524.           if target_col < w_left_column then
  13525.             -- we need to do something...
  13526.             redo_screen( target_col ) ;
  13527.             i_column_number := target_col ;
  13528.           else
  13529.             -- just move around....
  13530.             loop
  13531.             exit when moving_col = target_col ;
  13532.               put( ascii.bs ) ;
  13533.               put( ' '      ) ;
  13534.               put( ascii.bs ) ;
  13535.               moving_col := moving_col - 1 ;
  13536.             end loop ;
  13537.             i_column_number := moving_col ;
  13538.             txt.data_length := i_column_number - 1 ;
  13539.             get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13540.             no_text_on_current_line := ( ln_length = 0 ) ;
  13541.           end if ;
  13542.         end move_to_posn ;
  13543.          
  13544.         procedure up_one_line is
  13545.           -- if possible, move up one line , reset w_line_number etc...
  13546.           ln_start   : type_buffer_position ;
  13547.           -- change txt , buffer , i_column_number , screen's cursor
  13548.           -- also, set on_first_line_of_insertion if appropriate
  13549.           -- set cc to ascii.nul if unable to go up a line...
  13550.           -- check actual screen window boundries...
  13551.         begin -- up_one_line 
  13552.           -- first, we work on the buffer ...
  13553.           -- check for first line.....
  13554.           if on_first_line_of_insertion then
  13555.             cc := ascii.nul ; -- no line to move back to ...
  13556.             beep_the_bell ;
  13557.           elsIf cursor_backward_line then
  13558.               -- we can do it.....
  13559.             previous_line_start := master_buffer.fixed_cursor.line_start ;
  13560.             on_first_line_of_insertion 
  13561.               := master_buffer.fixed_cursor.file_line_number 
  13562.                  = cursor_position_at_insert_entry.file_line_number ;
  13563.             i_line_number := i_line_number - 1 ;
  13564.             w_line_number := w_line_number - 1 ;
  13565.             load_current_text ;
  13566.             -- clear the remaining portion of the line
  13567.             for posn in txt.data_length + 1 .. max_column_number loop
  13568.               txt.data(posn) := a_space; -- spaces...
  13569.             end loop ;
  13570.             get_leading( txt, leading_spaces, first_text, last_text, ln_length);
  13571.             no_text_on_current_line := ( ln_length = 0 ) ;
  13572.             no_text_ever_on_current_line := false ; -- to back up fast...
  13573.             current_line_is_bobs_word_processing_command 
  13574.                                        := character'val( txt.data(1) ) = '.' ;
  13575.             -- now, find out about old line
  13576.             i_column_number := last_text + 1 ;
  13577.             ln_start := master_buffer.fixed_cursor.line_start ;
  13578.             master_buffer.first_open_position 
  13579.                           := master_buffer.fixed_cursor.line_start ;
  13580.             previous_line_start := ln_start ;  -- don't forget where it was set
  13581.             -- Initialize a new blank line....
  13582.             for posn in ln_start .. ln_start + 2 loop
  13583.               master_buffer.e_buf( posn ).data := extended_character( 0 ) ;
  13584.               master_buffer.e_buf( posn ).attr := no_screen_attribute     ;
  13585.             end loop ;
  13586.             master_buffer.e_buf( ln_start + 3 ).data 
  13587.                             := extended_character( buffer_boundry ) ;
  13588.             -- now check w_line_number < 1 or i_column_number out ...
  13589.             -- now work on screen display... 
  13590.             if i_column_number > w_right_column then
  13591.               -- we must shift and re-do the screen
  13592.               shift(master_buffer,-max(15,i_column_number-w_right_column+5));
  13593.               redo_screen ( i_column_number ) ;
  13594.             elsif i_column_number < w_left_column then
  13595.               -- must shift and re-do screen
  13596.               shift(master_buffer,max(15,w_left_column-i_column_number + 5 ));
  13597.               redo_screen ( i_column_number ) ;
  13598.             elsif w_line_number < 1 then
  13599.               redo_screen ( i_column_number ) ;
  13600.             else
  13601.               -- must work it out....
  13602.               clear_end_of_screen(master_buffer, 
  13603.                                   w_line_number, i_column_number) ;
  13604.               if show_old_line_end then
  13605.                 out_end_of_line( w_line_number + 1 ) ;
  13606.               end if ;
  13607.               -- and position the cursor ...
  13608.               goto_line_column(master_buffer, w_line_number , i_column_number) ;
  13609.             end if ;
  13610.           else
  13611.             cc := ascii.nul ;
  13612.             error( "Unable to read last line. Temporary File Error.",
  13613.                    not_fatal_error , operator_wait , short_beep ) ;
  13614.           end if ;
  13615.         end up_one_line ;
  13616.          
  13617.       begin -- backup_char
  13618.         case cmd is
  13619.           when backward_character_command 
  13620.              | left_command           => if no_text_ever_on_current_line then
  13621.                                            -- in this case, they can move all
  13622.                                            -- the way back to first char posn
  13623.                                            if i_column_number > 1 then
  13624.                                              move_to_posn(i_column_number-1);
  13625.                                            else
  13626.                                              up_one_line ;
  13627.                                            end if ;
  13628.                                          else
  13629.                                            -- we have had text....
  13630.                                            if no_text_on_current_line then
  13631.                                              up_one_line ;
  13632.                                            else
  13633.                                              move_to_posn(i_column_number-1);
  13634.                                            end if ;
  13635.                                          end if ;
  13636.           when advance_word_command   
  13637.              | backward_word_command  => loop
  13638.                                            if i_column_number = 1 then
  13639.                                              cc := ascii.cr ;
  13640.                                              up_one_line ;
  13641.                                            else
  13642.                                              -- must move back one char..
  13643.                                              i_column_number :=
  13644.                                                i_column_number - 1 ;
  13645.                                              cc := char_at_position ;
  13646.                                              if cc = ascii.nul then
  13647.                                                i_column_number :=
  13648.                                                  i_column_number + 1 ;
  13649.                                              end if ;
  13650.                                            end if ;
  13651.                                          exit when 
  13652.                                              (   ((cc>='0') and (cc<='9'))
  13653.                                               or ((cc>='A') and (cc<='Z'))
  13654.                                               or ((cc>='a') and (cc<='z')) 
  13655.                                               or ( cc = ascii.nul )        ) ;
  13656.                                          end loop ;
  13657.                                          -- that moved past the current word
  13658.                                          -- now, move past trailing blanks.
  13659.                                          if cc /= ascii.nul then
  13660.                                            loop
  13661.                                              if i_column_number = 1 then
  13662.                                                cc := ascii.cr ;
  13663.                                                up_one_line ;
  13664.                                              else
  13665.                                                -- must move back one char..
  13666.                                                i_column_number :=
  13667.                                                  i_column_number - 1 ;
  13668.                                                cc := char_at_position ;
  13669.                                                if cc = ascii.nul then
  13670.                                                  i_column_number :=
  13671.                                                    i_column_number + 1 ;
  13672.                                                end if ;
  13673.                                              end if ;
  13674.                                            exit when ( cc = ascii.nul ) 
  13675.                                            or else not 
  13676.                                                (   ((cc>='0') and (cc<='9'))
  13677.                                                 or ((cc>='A') and (cc<='Z'))
  13678.                                                 or ((cc>='a') and (cc<='z')) ) ;
  13679.                                            end loop ;
  13680.                                          end if ;
  13681.                                          if cc /= ascii.nul then
  13682.                                            i_column_number := 
  13683.                                              i_column_number + 1 ;
  13684.                                          end if ;
  13685.                                          move_to_posn( i_column_number ) ;
  13686.           when backward_line_command  => cc := ascii.cr ;
  13687.                                          -- to end of prev line
  13688.                                          up_one_line ;
  13689.           when move_to_first_line_position_command => 
  13690.                                          move_to_posn( 1 ) ; -- 1st posn on line
  13691.           when others                 => null ; -- can't get here
  13692.         end case ;
  13693.       end backup_char ;
  13694.          
  13695.     begin -- do_insert_command 
  13696.       initialize_insert ;
  13697.       loop
  13698.         get_c_or_cmd( command_char , editor_command ) ;
  13699.         if editor_command /= advance_line_command 
  13700.         and editor_command /= forward_line_command then
  13701.           last_keystroke_was_return_on_non_wordp_command_line := false ;
  13702.           last_key_not_a_word_processor_command := true ;
  13703.         -- else is set correctly later in the case statement....
  13704.         end if ;
  13705.         case editor_command is
  13706.           when illegal_command => if command_char /= ascii.nul then
  13707.                                     -- is a character to put into line 
  13708.                                     -- is a real character...
  13709.                                     -- Now, put the character in...
  13710.                                     -- and then move right...
  13711.                                     do_char( command_char ) ;
  13712.                                   end if ;
  13713.           when advance_tab_command   
  13714.              | forward_tab_command  => do_a_tab ;
  13715.           when word_processor_command=> insert_word_processor_command( 
  13716.                                           word_processor_command_string ,
  13717.                                           word_processor_command_string_length);
  13718.           when left_command                    -- left 1 character 
  13719.              | backward_character_command 
  13720.              | advance_word_command
  13721.              | backward_word_command           -- left 1 word
  13722.              | backward_line_command           -- back to end of previous line
  13723.              | move_to_first_line_position_command -- to 1st position on line
  13724.                                     => backup_char( editor_command ) ;
  13725.           when advance_line_command 
  13726.              | forward_line_command => -- <cr> command, check for special
  13727.                if master_buffer.pagezero.enable_cmds
  13728.                and then not current_line_is_bobs_word_processing_command then
  13729.                  -- must check sufficiently...
  13730.                  if last_keystroke_was_return_on_non_wordp_command_line 
  13731.                  or else ( ( not last_key_not_a_word_processor_command )
  13732.                      and ( last_word_processor_key = new_paragraph_key 
  13733.                         or last_word_processor_key = add_one_line_key )) then
  13734.                    -- we definitely want an add one here...
  13735.                    insert_word_processor_command( add_one_line_key ,
  13736.                                                   add_one_line_key_length ) ;
  13737.                    last_keystroke_was_return_on_non_wordp_command_line := false;
  13738.                  elsif master_buffer.pagezero.filling then
  13739.                    insert_word_processor_command( new_paragraph_key ,
  13740.                                                   new_paragraph_key_length) ;
  13741.                    last_keystroke_was_return_on_non_wordp_command_line := false;
  13742.                  else
  13743.                    last_keystroke_was_return_on_non_wordp_command_line
  13744.                      := not current_line_is_bobs_word_processing_command ;
  13745.                    start_next_line ;
  13746.                  end if ;
  13747.                else
  13748.                  last_keystroke_was_return_on_non_wordp_command_line 
  13749.                    := not current_line_is_bobs_word_processing_command ;
  13750.                  start_next_line ;
  13751.                end if ;
  13752.           when accept_command  => null ;          -- handled outside this loop
  13753.           when reject_command  => null ;          -- handled outside this loop
  13754.           when up_command      => beep_the_bell ; -- null ; -- for now...
  13755.           when down_command    => beep_the_bell ; -- null ; -- for now...
  13756.           when right_command   => beep_the_bell ; -- null ; -- for now...
  13757.           when others          => beep_the_bell ; -- null ; -- skip them......
  13758.                                   -- show_buffer ( 'V' ) ;
  13759.         end case ;
  13760.       exit when editor_command = accept_command 
  13761.              or editor_command = reject_command ;
  13762.       end loop ;
  13763.       finish_Insert ( editor_command ) ;
  13764.     exception
  13765.       when no_room_for_insert => finish_insert ( accept_command ) ;
  13766.     end do_insert_command ;
  13767.        
  13768.   begin -- insert_package 
  13769.     -- INSERT   by SAIC/Clearwater Insert Package              14 Jan 85
  13770.     null ;
  13771.   end insert_package ;
  13772.    
  13773.   --$$$- INSERT
  13774.  
  13775. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  13776. --edit
  13777. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  13778.  
  13779.   --$$$+ EDIT
  13780.     
  13781.   --
  13782.   -- File 021
  13783.   --
  13784.   -- Editor Written By Robert S. Cymbalski
  13785.   --                   Science Applications International Corporation
  13786.   --                   Energy Systems Group
  13787.   --                   Ada Software Development Project Team
  13788.   --                   2280 U.S. Highway 19 North, Suite 120
  13789.   --                   Clearwater, Florida  33575
  13790.   --
  13791.   -- Main Program Written 12 Nov 84 - RSC
  13792.   --              revised 26 Dec 84 - RSC
  13793.   --
  13794.   --
  13795.   -- Editor Revised from text Copyright (c) 1984 , R.S.Cymbalski
  13796.   -- 
  13797.        
  13798.   with string_library  ;
  13799.   use  string_library  ;
  13800.    
  13801.   with basic_io_system ;
  13802.    
  13803.   with crt_customization ;
  13804.   use  crt_customization ;
  13805.   use  crt               ;
  13806.   use  editor_customization ;
  13807.     
  13808.   with Wordp_Globals   ;
  13809.   use  Wordp_Globals   ;
  13810.  
  13811.   with editor_globals         ;
  13812.   use  editor_globals         ;
  13813.     
  13814.   with editor_misc            ;
  13815.   use  editor_misc            ;
  13816.   use  copy_package ;
  13817.     
  13818.   with buffer_package  ;
  13819.   use  buffer_package  ;
  13820.   use  buffer_block_io ;
  13821.   use  buffer_general  ;
  13822.    
  13823.   with editor_files           ;
  13824.   use  editor_files           ;
  13825.     
  13826.   with editor_main_packages   ;
  13827.   use  editor_main_packages   ;
  13828.     
  13829.   with insert_package         ; -- Insert Text
  13830.   use  insert_package         ; -- Insert Text
  13831.     
  13832.   with movement_package       ; -- The do_move_command is in this package 
  13833.   use  movement_package       ; -- & home & Jump Commands 
  13834.     
  13835.   with editor_more_packages   ;
  13836.   use  editor_more_packages   ;
  13837.     
  13838.   with editor_even_more_packages ;
  13839.   use  editor_even_more_packages ;
  13840.      
  13841.   with debugger               ;
  13842.     
  13843.   with editor_find ;
  13844.   use  editor_find ;
  13845.    
  13846.   package editor is
  13847.     
  13848.     procedure TEXT_EDITOR(SOURCE_FILE     : in  ASCII_TEXT_FILE_NAME ;
  13849.                           DESTINATION_FILE: in  ASCII_TEXT_FILE_NAME);
  13850.     -- This tool allows a SOURCE_FILE to be edited.  Either file name may
  13851.     -- be empty, in which case the editor will prompt for the input file
  13852.     -- and give standard output file options.
  13853.     
  13854.   end ;
  13855.      
  13856.   package body editor is
  13857.       
  13858.     procedure TEXT_EDITOR(SOURCE_FILE     : in  ASCII_TEXT_FILE_NAME;
  13859.                           DESTINATION_FILE: in  ASCII_TEXT_FILE_NAME)
  13860.                           is
  13861.       -- This tool allows a SOURCE_FILE to be edited.  Either file name may
  13862.       -- be empty, in which case the editor will prompt for the input file
  13863.       -- and give standard output file options.
  13864.       
  13865.       partial_quit_request: boolean           ;
  13866.       total_quit_request :  boolean           ;
  13867.       Loaded_A_File      :  boolean           ;
  13868.        
  13869.       procedure err( s : string ) is
  13870.         c : extended_character ;
  13871.         
  13872.       begin
  13873.         basic_io_system.put_line;
  13874.         basic_io_system.put_line;
  13875.         basic_io_system.put( "Exception: " & s ) ;
  13876.         basic_io_system.put_line;
  13877.         basic_io_system.put_line;
  13878.         basic_io_system.put_line;
  13879.         for buf in 1 .. max_buffer_number loop
  13880.           if buffer_list( buf ) /= null then
  13881.             buffer_package.dispose_buffer( buffer_list( buf ) ) ;
  13882.           end if ;
  13883.         end loop ;
  13884.         basic_io_system.put ( "  Type <space> to continue.... ");
  13885.         c := basic_io_system.get_transparent ;
  13886.         terminate_copy_package ;
  13887.       end err ;
  13888.         
  13889.     begin  -- Text_Editor
  13890.       editor_master_reset ;
  13891.         -- Initialize the entire text editor.  
  13892.       loop
  13893.         -- This is for the multiple entries of the editor 
  13894.         editor_re_initialize( Loaded_A_File ) ;
  13895.         go_forward    := true ;
  13896.         current_repeat_factor := 0 ; -- to cause command to show it as [ Once]
  13897.         set_direction ( go_forward ) ;
  13898.         total_quit_request   := false ;
  13899.         -- Repeat Factor is the only item which is set in this main 
  13900.         -- Procedure which is available to the called procedures...
  13901.         -- Go forward is used here also...
  13902.         If Loaded_A_File then
  13903.           current_command := illegal_command ; -- to force a read...
  13904.         else
  13905.           current_command := insert_command ; 
  13906.                                       -- Automatically go into insert mode if 
  13907.                                       -- no file name was given upon entry
  13908.         end if;
  13909.         loop
  13910.           partial_quit_request := false ;
  13911.           if need_prompt then
  13912.             set_direction( go_forward ) ;
  13913.           end if ;
  13914.           if current_command = illegal_command then
  13915.             get_next_command( current_repeat_factor , current_repeat_factor , 
  13916.                               current_command ); 
  13917.           end if ;
  13918.           case current_command is
  13919.             when up_command
  13920.                | down_command
  13921.                | right_command
  13922.                | left_command
  13923.                | forward_character_command  
  13924.                | backward_character_command 
  13925.                | forward_word_command  
  13926.                | backward_word_command 
  13927.                | forward_tab_command   
  13928.                | backward_tab_command  
  13929.                | forward_line_command
  13930.                | backward_line_command
  13931.                | forward_paragraph_command
  13932.                | backward_paragraph_command
  13933.                | forward_page_command  
  13934.                | backward_page_command 
  13935.                | home_command          
  13936.                | move_to_first_line_position_command 
  13937.                | move_to_last_line_position_command  
  13938.                | jump_to_first_position_command 
  13939.                | jump_to_last_position_command  
  13940.                | jump_to_marked_position_command 
  13941.                    => do_move_command( current_command, current_repeat_factor) ;
  13942.             when advance_character_command   
  13943.                    => if go_forward then
  13944.                         do_move_command ( forward_character_command ,
  13945.                                           current_repeat_factor ) ;
  13946.                       else
  13947.                         do_move_command ( backward_character_command ,
  13948.                         current_repeat_factor ) ;
  13949.                       end if;
  13950.             when advance_word_command   
  13951.                    => if go_forward then
  13952.                         do_move_command ( forward_word_command ,
  13953.                                           current_repeat_factor ) ;
  13954.                       else
  13955.                         do_move_command ( backward_word_command ,
  13956.                         current_repeat_factor ) ;
  13957.                       end if;
  13958.             when advance_tab_command   
  13959.                    => if go_forward then
  13960.                         do_move_command ( forward_tab_command ,
  13961.                                           current_repeat_factor ) ;
  13962.                       else
  13963.                         do_move_command ( backward_tab_command ,
  13964.                         current_repeat_factor ) ;
  13965.                       end if;
  13966.             when advance_line_command   
  13967.                    => if go_forward then
  13968.                         do_move_command ( forward_line_command ,
  13969.                                           current_repeat_factor ) ;
  13970.                       else
  13971.                         do_move_command ( backward_line_command ,
  13972.                         current_repeat_factor ) ;
  13973.                       end if;
  13974.             when advance_paragraph_command   
  13975.                    => if go_forward then
  13976.                         do_move_command ( forward_paragraph_command ,
  13977.                                           current_repeat_factor ) ;
  13978.                       else
  13979.                         do_move_command ( backward_paragraph_command ,
  13980.                         current_repeat_factor ) ;
  13981.                       end if;
  13982.             when advance_page_command   
  13983.                    => if go_forward then
  13984.                         do_move_command ( forward_page_command ,
  13985.                                           current_repeat_factor ) ;
  13986.                       else
  13987.                         do_move_command ( backward_page_command ,
  13988.                         current_repeat_factor ) ;
  13989.                       end if;
  13990.             when advance_infinity_command   
  13991.                    => if go_forward then
  13992.                         do_move_command ( jump_to_first_position_command ,
  13993.                                           current_repeat_factor ) ;
  13994.                       else
  13995.                         do_move_command ( jump_to_last_position_command ,
  13996.                                           current_repeat_factor ) ;
  13997.                       end if;
  13998.             when set_forward_direction => go_forward := true ;
  13999.                                           set_direction ( go_forward ) ;
  14000.                                           show_cursor ;
  14001.                                           current_command := illegal_command ;
  14002.             when set_backward_direction=> go_forward := false ;
  14003.                                           set_direction ( go_forward ) ;
  14004.                                           show_cursor ;
  14005.                                           current_command := illegal_command ;
  14006.             when shift_screen_right    => shift_screen( -current_repeat_factor);
  14007.                                           current_command := illegal_command ;
  14008.             when shift_screen_left     => shift_screen( current_repeat_factor );
  14009.                                           current_command := illegal_command ;
  14010.             when adjust_command        => do_adjust_command ;
  14011.                                           current_command := illegal_command ;
  14012.             when copy_command          => do_copy_command ;
  14013.                                           current_command := illegal_command ;
  14014.             when start_deletion_command=> do_move_command( 
  14015.                                                       start_deletion_command,1);
  14016.             when find_command          => do_find_command (go_forward,
  14017.                                                           current_repeat_factor,
  14018.                                                           current_command) ;
  14019.                                             -- Under certain circumstances,
  14020.                                             -- this find command can return
  14021.                                             -- a request to Q(uit
  14022.                                           if current_command/= quit_command then
  14023.                                             current_command := illegal_command ;
  14024.                                           end if ;
  14025.             when help_command          => do_help_command ;
  14026.                                           need_prompt := true ;
  14027.                                           show_screen( master_buffer, 
  14028.                                             master_buffer.fixed_cursor, 0 );
  14029.                                           current_command := illegal_command ;
  14030.             when insert_command        => do_insert_command ;
  14031.                                           current_command := illegal_command ;
  14032.             when jump_command          => do_jump_command ;
  14033.                                           current_command := illegal_command ;
  14034.             when kill_command          => do_kill_command ( go_forward );
  14035.                                           current_command := illegal_command ;
  14036.             when print_screen_command  => do_printer_command ;
  14037.                                           current_command := illegal_command ;
  14038.             when re_margin_command     => do_re_margin_command (
  14039.                                             master_buffer.fixed_cursor ,
  14040.                                             true , current_repeat_factor ) ;
  14041.                                           current_command := illegal_command ;
  14042.             when quit_command          => do_quit_command (
  14043.                                             partial_quit_request,
  14044.                                             total_quit_request);
  14045.                                         -- quit_partial =>partial_quit_request
  14046.                                         -- quit_total   =>total_quit_request; 
  14047.                                           if not ( partial_quit_request 
  14048.                                                    or total_quit_request ) then
  14049.                                             set_direction(go_forward);
  14050.                                           end if ;
  14051.                                           current_command := illegal_command ;
  14052.             when replace_command       => do_find_command (go_forward,
  14053.                                                           current_repeat_factor,
  14054.                                                           current_command ) ;
  14055.                                             -- Under certain circumstances,
  14056.                                             -- this replace command can return
  14057.                                             -- a request to Q(uit
  14058.                                           if current_command/= quit_command then
  14059.                                             current_command := illegal_command ;
  14060.                                           end if ;
  14061.             when set_stuff_command     => do_set_information_command   ;
  14062.                                           current_command := illegal_command ;
  14063.             when verify_screen_command => do_verify_screen_command ;
  14064.                                           current_command := illegal_command ;
  14065.             when enter_exchange_mode   => do_enter_exchange_mode ;
  14066.                                           current_command := illegal_command ;
  14067.             when zap_command           => do_zap_command ;
  14068.                                           -- debugger.show_buffer ;
  14069.                                           current_command := illegal_command ;
  14070.             when accept_command        => do_end_open_commands(accept_command) ;
  14071.                                           current_command := illegal_command ;
  14072.             when reject_command        => do_end_open_commands(reject_command) ;
  14073.                                           current_command := illegal_command ;
  14074.               
  14075.             when illegal_command   
  14076.                | digit_command
  14077.                | infinity_command
  14078.                | show_other_prompt_command
  14079.                | word_processor_command=> current_command := illegal_command ;
  14080.           end case ; 
  14081.         exit when partial_quit_request or total_quit_request ;
  14082.         end loop;
  14083.       exit when total_quit_request ;
  14084.       end loop;
  14085.       terminate_copy_package ;
  14086.     exception
  14087.       -- when user_abort        => null ;
  14088.       when constraint_error  => err("Constraint Error");
  14089.       when numeric_error     => err("Numeric Error");
  14090.       when program_error     => err("Program Error");
  14091.       when storage_error     => err("Storage Error");
  14092.       when tasking_error     => err("Tasking Error");
  14093.       when others            => err("Unknown Error");
  14094.     end text_editor ;
  14095.          
  14096.   begin -- Editor 
  14097.     -- EDIT     by SAIC/Clearwater Main Text Editor Package    26 Dec 84
  14098.     -- text_editor(no_file , no_file ) ;
  14099.     -- crt.do_crt ( crt.program_termination ) ;
  14100.     null ;
  14101.   end editor ;
  14102.    
  14103.   --$$$- EDIT
  14104.  
  14105. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  14106. --rune.TXT;compile]edit
  14107. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  14108.  
  14109.   --$$$+ rune
  14110.  
  14111.   with crt_customization ;
  14112.   use  crt_customization ;
  14113.    
  14114.   with Wordp_Globals   ;
  14115.   use  Wordp_Globals   ;
  14116.  
  14117.   with editor    ;
  14118.   use  editor    ;
  14119.   
  14120.   Procedure RunE is
  14121.   
  14122.   begin -- RunE ;
  14123.     text_editor( no_file , no_file ) ;
  14124.     crt.do_crt ( crt.program_termination ) ;
  14125.   end RunE ;
  14126.    
  14127.   --$$$- rune
  14128.  
  14129.