! ! EVElse: Eve modified to add EVE extensions to LSE Page 1 ! ! EVE - { Extensible | Easy | Efficient } Vax Editor ! ! COPYRIGHT © 1983, 1984, 1985 BY ! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS ! ALL RIGHTS RESERVED ! ! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ! ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE ! INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER ! COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY ! OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY ! TRANSFERRED. ! ! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE ! AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT ! CORPORATION. ! ! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. ! !++ ! FACILITY: ! Text Processing Utility (VAXTPU) ! ! ABSTRACT: ! This is the source program for the EVE interface ! ! ENVIRONMENT: ! VAX/VMS ! !Author: Michael Good ! ! CREATION DATE: 27-October-1983 ! ! MODIFIED BY: ! Mike Boorman MEE-8, Los Alamos National Laboratory ! date: 6/3/87 ! reason: EVElse mods !-- ! ! EVESECINI.TPU ! ! Table of Contents as of 2-Oct-1985 ! ! Procedure name Page Description ! -------------- ---- ------------ ! ! eve$init_variables 2 Utility procedures ! eve$current_word 3 ! eve$at_start_of_word 4 ! eve$start_of_word 5 ! eve$end_of_word 6 ! eve$append_line 7 ! eve$capitalize_string 8 ! eve$alphabetic 9 ! eve$cleanse_string 9 ! eve$lookup_comment 9 ! eve$prompt_key 10 ! eve$prompt_number 11 ! eve$prompt_string 12 ! eve$show_first_line 13 ! eve$position_in_middle 14 ! eve$expand_to_choices 15 ! eve$add_choice 15 ! eve$get_choice 16 ! eve$strip_choices 16 ! eve$format_choices 17 ! eve$display_choices 17 ! eve$letter_wrap 18 ! eve$to_column 19 ! eve$indent_line_to 19 ! eve$trim_line 20 ! eve$trim_buffer 20 ! eve$set_status_line 21 ! eve$update_status_lines 22 ! eve_change_direction 23 Keypad commands ! eve_change_mode 23 ! eve_delete 24 ! eve_erase_word 25 ! eve$compress_whitespace 26 ! eve_exit 27 ! eve_find 28 ! eve$find 29 ! eve_help 30 ! eve$help_text 31 ! eve$help_keypad 32 ! eve_move_by_line 33 ! eve_move_down 34 ! eve_move_left 34 ! eve_move_right 34 ! eve_move_up 34 ! eve_next_screen 35 ! eve_previous_screen 35 ! eve$move_by_screen 36 ! eve_return 37 ! eve$split_line 37 ! eve_select 38 ! eve_remove 39 ! eve_insert_here 40 ! eve_space 41 ! eve$fill_line 42 ! eve$backup_over_whitespace 43 ! eve_tab 44 ! eve_bottom 45 Editing commands ! eve_top 45 ! eve_capitalize_word 46 ! eve_center_line 47 ! eve_end_of_line 48 ! eve_erase_character 49 ! eve_erase_line 50 ! eve_erase_previous_word 51 ! eve_erase_start_of_line 52 ! eve_fill_paragraph 53 ! eve$paragraph_break 54 ! eve_forward 55 ! eve_reverse 55 ! eve_go_to 56 ! eve_insert_mode 57 ! eve_overstrike_mode 57 ! eve_line 58 ! eve_lowercase_word 59 ! eve_uppercase_word 59 ! eve_mark 60 ! eve_move_by_word 61 ! eve_quit 62 ! eve_quote 63 ! eve_replace 64 ! eve_restore 65 ! eve_set_left_margin 66 ! eve_set_right_margin 67 ! eve_start_of_line 68 ! eve$check_bad_window 69 File and window commands ! eve_buffer 70 ! eve_get_file 71 ! eve$create_buffer 72 ! eve_include_file 73 ! eve_one_window 74 ! eve_other_window 75 ! eve_two_windows 76 ! eve_write_file 77 ! eve_refresh 78 Additional screen commands ! eve_set_tabs_at 79 ! eve_set_tabs_every 80 ! eve_set_width 81 ! eve_shift_left 82 ! eve_shift_right 82 ! eve_show 83 ! eve$show_buffer_info 84 ! eve_attach 85 Advanced commands ! eve_dcl 86 ! eve_define_key 87 ! eve_extend_tpu 88 ! eve_learn 89 ! eve_remember 89 ! eve_repeat 90 ! eve_save_extended_tpu 91 ! eve_set_shift_key 92 ! eve$get_shift_key 92 ! eve_spawn 93 ! eve_tpu 94 ! eve$enter_command_window 95 Command line parser ! eve$exit_command_window 95 ! eve$process_command 96 ! eve_recall 97 ! eve_do 98 ! eve$index_over_whitespace 99 ! eve$get_token 100 ! eve$complete 101 ! eve$double_quotes 102 ! eve$add_final_string 103 ! eve$parse 104 ! 105 Key map and key map list usage ! eve$standard_keys 106 ! eve$vt200_keys 107 ! eve$vt100_keys 108 ! tpu$local_init 109 ! eve$init_buffer 110 ! eve$insert_text 111 Copy_text in insert mode ! eve$overstrike_text 111 Copy_text in overstrike mode ! eve$find_buffer 112 Find a buffer by name ! eve$unmap_if_mapped 113 Unmap a window ! eve$map_if_not_mapped 113 Map window ! eve$create_buffer_globals 114 ! eve$parser_dispatch 114 ! eve$package_init 114 ! tpu$init_procedure 115 ! eve$init_windows 115 ! eve$init_buffers 115 ! eve$init_files 115 ! eve$init_settings 115 ! eve$init_procedure 115 ! Page 2 ! ! As documented in the User's Guide to EVE, procedures with names beginning ! with eve_ are EVE commands. The procedures with names beginning with eve$ ! may be useful in extending EVE. However, these procedures are subject to ! change. In the future, Digital may supply new procedures beginning with ! eve$, remove some of the eve$ procedures, or change existing eve$ ! procedures. The same is true for global variables with names beginning ! with eve$. User-written procedures should not begin with eve$. ! Initialize Eve variables ! Global variables should be initialized to eliminate the possible ! confusion of global variables with procedure names procedure eve$init_variables ! Utility procedures ! Global string constants eve$kt_version := "Eve Version V1.1-024"; ! Eve version number eve$kt_null := ""; ! Null string eve$kt_spaces := ! Used for padding " "; eve$kt_beyond_eol := "beyond_eol"; ! Argument to get_info eve$kt_buffer := "buffer"; ! Argument to get_info eve$kt_current_row := "current_row"; ! Argument to get_info eve$kt_file_name := "file_name"; ! Argument to get_info eve$kt_first := "first"; ! Argument to get_info eve$kt_last := "last"; ! Argument to get_info eve$kt_left_margin := "left_margin"; ! Argument to get_info eve$kt_mode := "mode"; ! Argument to get_info eve$kt_name := "name"; ! Argument to get_info eve$kt_offset_column := "offset_column"; ! Argument to get_info eve$kt_output_file := "output_file"; ! Argument to get_info eve$kt_record_count := "record_count"; ! Argument to get_info eve$kt_right_margin := "right_margin"; ! Argument to get_info eve$kt_type := "type"; ! Argument to get_info eve$kt_visible_length := "visible_length"; ! Argument to get_info eve$kt_visible_top := "visible_top"; ! Argument to get_info eve$kt_width := "width"; ! Argument to get_info ! Global integer constants eve$k_no_arg := -2147483648; ! Place holder when no argument is specified ! Global boolean constants true := 1; false := 0; ! Global keyword variables eve$x_highlighting := reverse; ! Highlighting used by select and replace ! Global pattern variables eve$pattern_end_of_word := ! End of a word ! Don't move off current character position ( anchor & ! If on eol,then match that ( (line_end) | ! Leading spaces, on a word delimiter ( (span (eve$x_whitespace)) & (any (eve$x_word_separators) | ''))) | ! No leading spaces, on a word delimiter, move one past it (any (eve$x_word_separators)) | ! No leading spaces, on a real word, go one beyond it (scan (eve$x_word_separators)) | ! No leading spaces, on a last real word of line, match reat of line remain ) & ! After matching, skip over trailing spaces if any, ! except if match occurred at the eol. In this case, don't skip over blanks (line_begin | span (eve$x_whitespace) | '') ; eve$pattern_paragraph_break := ! Blank line or Runoff command line anchor & line_begin & (("." & any (eve$x_runoff_characters)) | ((eve$kt_null | span (eve$x_word_separators)) & line_end)); eve$pattern_startprocedure := ! Start of a VAXTPU procedure line_begin & "procedure" & span (eve$x_word_separators); eve$pattern_afterprocname := ! What you can find after a procedure name line_end | any (eve$x_word_separators) | any (";!("); eve$pattern_endprocedure := ! End of a VAXTPU procedure (line_begin & "endprocedure") & (line_end | any (eve$x_word_separators) | any (";!")); eve$pattern_procname := ! VAXTPU procedure name anchor & (span (eve$x_symbol_characters) | remain); eve$pattern_whitespace := anchor & (span (eve$x_whitespace)); eve$pattern_trim := span (" ") & line_end; ! Used for trimming buffer ! Global string variables ! The following three are provided only for compatability reasons ! The coresponding eve$_... string "constants" should be used instead ! These variables may be deleted in future versions. eve$x_version := eve$kt_version;! Eve version number eve$x_null := eve$kt_null; ! Null string eve$x_spaces := eve$kt_spaces; ! Used for padding eve$x_word_separators := ! Word separators: space, horizontal tab, ! form feed, carriage return, vertical tab, ! and line feed " "; eve$x_fill_separators := ! Fill separators: space, horizontal tab, ! form feed, carriage return, vertical tab, ! and line feed " "; eve$x_whitespace := " "; ! Whitespace characters: space & horizontal tab eve$x_token_separators := ! Token separators: space and horizontal tab " "; eve$x_symbol_characters := ! Symbol characters are alphanumerics plus ! "$" and "_", including multinational ! character set "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890$_" + "àáâãäåæçèéêëìíîïñòóôõö÷øùúûüýÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÑÒÓÔÕÖ×ØÙÚÛÜÝß"; eve$x_runoff_characters := ! Characters used to begin Runoff commands "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!;"; eve$x_digit_characters := ! Digits - allow lowercase l for numeral 1 "0123456789l"; eve$x_not_alphabetic := ! Non-alphabetic graphic characters "!@#$%^&*()[]{}-_+=~`|\:;""'<,>.?/¡¢£¥§¨©ª«°±²³µ¶·¹º»¼½¿"; eve$x_command_prompt := ! Command prompt for Do key "Command: "; eve$x_eve_command_prompt := ! Command prompt used in eve_define_key "Eve command: "; ! Global (uninitialized) string variables eve$x_argument_type := eve$kt_null; ! Type of argument expected by eve$parse ! Can be "integer" or "string" eve$x_command_line := eve$kt_null; ! Command as typed after pressing Do eve$x_do_line := eve$kt_null; ! Last line given to do command eve$x_parsed_do_line := eve$kt_null; ! Parsed version of eve$x_do_line eve$x_restore_text := eve$kt_null; ! String to be inserted by restore command eve$x_target := eve$kt_null; ! Last string given to find command eve$x_start_do_key := eve$kt_null; ! Key (comment) that started a DO sequence eve$x_stop_do_key := eve$kt_null; ! Key (comment) that ended a DO sequence ! Global key map variables eve$x_key_map_list := "TPU$KEY_MAP_LIST"; ! EVE's default key map list eve$x_user_keys := "eve$user_keys"; ! Keys defined by user eve$x_vt100_keys := "eve$vt100_keys"; ! VT100 numeric keypad eve$x_vt200_keys := "eve$vt200_keys"; ! VT200 numeric keypad eve$x_standard_keys := "eve$standard_keys"; ! Main EVE keys ! Global marker variables eve$x_select_position := 0; ! Marker for start of select range ! Global window variables eve$x_pre_command_window := 0; ! Current window when Do key is pressed eve$x_this_window := 0; ! Current text window using Eve window commands ! Global process varibles eve$x_dcl_process := 0; ! DCL subprocess used by DCL command ! Global integer variables eve$x_choice_window_length := 6; ! Length of window where choices are displayed ! for ambiguous commands, files, buffers, etc. eve$x_command_prompt_length := 9; ! Length of eve$x_command_prompt eve$x_default_left_margin := 1; ! Left margin for new buffers eve$x_default_right_margin := 1; ! Amount to subtract from window width ! for right margin for new buffers eve$x_hot_zone_size := 8; ! Number of characters before right margin ! where word wrap will occur eve$x_largest_right_margin := 983;! Maximum value allowed by set (margins...) eve$x_largest_width := 65535; ! Maximum value allowed by set (width...) eve$x_max_buffer_name_length := 43; ! Buffer names can be any size, but this is ! the largest size that will be shown on ! the status line without being truncated eve$x_max_mark_length := 82; ! 132 - 50 (see execute's in go to and show) eve$x_max_scroll_offset := 4; ! Maximum number of lines above/below the ! final position of a find command eve$x_ambiguous_parse := 0; ! True when choices are being displayed eve$x_buffer_of_mark := 0; ! Used by go to command eve$x_command_index := 1; ! Index into eve$x_command_line while parsing eve$x_command_length := 0; ! Length of eve$x_command_line eve$x_command_line_flag := 0; ! True while a command line is executing eve$x_is_number := 0; ! True if current token is a number eve$x_is_symbol := 0; ! True if current token is a symbol eve$x_is_quoted_string := 0; ! True if current token is a quoted string eve$x_is_punctuation := 0; ! True if current token is punctuation eve$x_number_of_windows := 1; ! Number of windows currently being displayed eve$x_repeat_count := 1; ! Number of times to execute current command eve$x_restoring_line := 0; ! True if restore command needs to do a ! split_line after the copy_text eve$x_starting_up := 1; ! True during eve$init_procedure eve$x_trimming := 0; ! True if lines should be trimmed of ! extra spaces before writing files eve$x_vt200_keypad := 1; ! True if LK201 keyboard is being used ! Argument information for eve$parse eve$arg1_buffer := "string"; eve$arg1_dcl := eve$arg1_buffer; eve$arg1_define_key := eve$arg1_buffer; eve$arg1_do := eve$arg1_buffer; eve$arg1_extend_tpu := eve$arg1_buffer; eve$arg1_find := eve$arg1_buffer; eve$arg1_get_file := eve$arg1_buffer; eve$arg1_go_to := eve$arg1_buffer; eve$arg1_help := eve$arg1_buffer; eve$arg1_include_file := eve$arg1_buffer; eve$arg1_line := "integer"; eve$arg1_mark := eve$arg1_buffer; eve$arg1_repeat := eve$arg1_line; eve$arg1_replace := eve$arg1_buffer; eve$arg2_replace := eve$arg1_buffer; eve$arg1_save_extended_tpu := eve$arg1_buffer; eve$arg1_set_left_margin := eve$arg1_line; eve$arg1_set_right_margin := eve$arg1_line; eve$arg1_set_tabs_at := eve$arg1_buffer; eve$arg1_set_tabs_every := eve$arg1_line; eve$arg1_set_width := eve$arg1_line; eve$arg1_shift_left := eve$arg1_line; eve$arg1_shift_right := eve$arg1_line; eve$arg1_tpu := eve$arg1_buffer; eve$arg1_write_file := eve$arg1_buffer; endprocedure; ! Page 3 ! Returns a range for the current word (the next word if between words). ! Cursor moves to end of the word. Returns 0 if no current word. ! Used by change-case commands and others. procedure eve$current_word local start_current_word, ! Marker for start of range end_current_word, ! Marker for end of range this_position; ! Marker for current cursor position this_position := mark (none); if this_position = end_of (current_buffer) then return (0); endif; if current_character = eve$kt_null then move_horizontal (1); return (create_range (this_position, this_position, none)); endif; ! If current character is a word separator, go to next word if index (eve$x_word_separators, current_character) <> 0 then eve$end_of_word; endif; ! Go to end of word first - eve$start_of_word goes back a word ! when current cursor is at the start of a word eve$end_of_word; move_horizontal (-1); end_current_word := mark (none); move_horizontal (1); eve$start_of_word; start_current_word := mark (none); eve$end_of_word; return (create_range (start_current_word, end_current_word, none)); endprocedure; ! Page 4 ! Tests for start of word. Returns true or false. procedure eve$at_start_of_word if current_offset = 0 then return (1); endif; if index (eve$x_word_separators, current_character) = 0 then move_horizontal (-1); if index (eve$x_word_separators, current_character) <> 0 then eve$at_start_of_word := 1; else eve$at_start_of_word := 0; endif; move_horizontal (1); else eve$at_start_of_word := 0; endif; endprocedure; ! Page 5 ! Go to the beginning of a word. Return amount moved, or 0 if at ! start of line. procedure eve$start_of_word local temp_length, ! Distance moved temp_char; ! Character to check if current_offset = 0 then return (0); endif; move_horizontal (-1); ! Skip current character temp_length := 1; ! Count any spaces loop exitif current_offset = 0; exitif index (eve$x_whitespace, current_character) = 0; move_horizontal (-1); temp_length := temp_length + 1; endloop; ! If we are on a word terminator count that one character. ! Otherwise scan to the next word terminator. if (index (eve$x_word_separators, current_character) = 0) then loop exitif current_offset = 0; move_horizontal (-1); if (index (eve$x_word_separators, current_character) <> 0) then move_horizontal (1); exitif 1; endif; temp_length := temp_length + 1; endloop; endif; return (temp_length); endprocedure; ! Page 6 ! Find the end of the word procedure eve$end_of_word local temp_length, ! Distance moved temp_range; ! Range from current position to end of word on_error ! Suppress "string not found" error message return (0); endon_error; if current_character = eve$kt_null then return (0); endif; temp_range := search (eve$pattern_end_of_word, forward); temp_length := length (temp_range); move_horizontal (temp_length); return (temp_length); endprocedure; ! Page 7 ! Append line, deleting whitespace in left margin procedure eve$append_line local this_position, ! Marker for current cursor position how_many_chars, ! How many characters to erase during append all_spaces, ! True if all spaces in left margin left_margin, ! Current left margin this_line, ! Current line this_line_index, ! Index into this_line this_line_length; ! Length of this_line left_margin := get_info (current_buffer, eve$kt_left_margin); this_position := mark (none); if (get_info (current_buffer, eve$kt_offset_column) > left_margin) or (this_position = beginning_of (current_buffer)) then return (0); endif; if this_position = end_of (current_buffer) then move_horizontal (-1); if (current_offset = 0) then erase_line; endif; return (1); endif; move_horizontal (- current_offset); how_many_chars := 0; all_spaces := 1; ! Check to see if everything in the margin is spaces loop exitif current_character = eve$kt_null; exitif get_info (current_buffer, eve$kt_offset_column) = left_margin; if index (eve$x_word_separators, current_character) > 0 then how_many_chars := how_many_chars + 1; move_horizontal (1); else all_spaces := 0; exitif 1; endif; endloop; if all_spaces then erase_character (- how_many_chars); ! Check for a line of all spaces - primarily for overstrike deletes this_line := current_line; this_line_index := 1; this_line_length := length (this_line); loop exitif this_line_index > this_line_length; exitif substr (this_line, this_line_index, 1) <> " "; this_line_index := this_line_index + 1; endloop; if this_line_index > this_line_length then erase_line; move_horizontal (-1); else append_line; endif; eve$append_line := 1; else ! Otherwise there were characters in the left margin ! If at start of line, delete the leading spaces and ! append the line; else act like the delete key position (this_position); if current_offset = 0 then erase_character (how_many_chars); append_line; eve$append_line := 1; else if get_info (current_buffer, eve$kt_mode) = overstrike then move_horizontal (-1); copy_text (" "); move_horizontal (-1); else erase_character (-1); endif; eve$append_line := 0; endif; endif; endprocedure; ! Page 8 ! Capitalize a string - like change_case (string, capital) would be ! Ignore leading punctuation, so things like "Hi" and (foo) can be ! capitalized. ! ! Parameters: ! ! cap_string String to be capitalized - input/output procedure eve$capitalize_string (cap_string) local initial_letter, ! Initial substring ending at first letter initial_index, ! Loop index used in search for first letter cap_string_length, ! Length of cap_string parameter rest_of_string; ! Remainder of cap_string after initial_letter initial_index := 1; cap_string_length := length (cap_string); loop initial_letter := substr (cap_string, 1, initial_index); exitif initial_index = cap_string_length; exitif index (eve$x_not_alphabetic, substr (cap_string, initial_index, 1)) = 0; initial_index := initial_index + 1; endloop; rest_of_string := substr (cap_string, initial_index + 1, cap_string_length); change_case (initial_letter, upper); change_case (rest_of_string, lower); cap_string := initial_letter + rest_of_string; endprocedure; ! Page 9 ! Procedure to check if a key is a printing character (in DEC Multinational ! set). Returns the character if alphabetic, else returns the null string. ! ! Parameters: ! ! this_key Keyword of key to check - input procedure eve$alphabetic (this_key) local ascii_key; ! String for this_key ascii_key := ascii (this_key); if ascii_key = ascii (0) then return (eve$kt_null); else return (ascii_key); endif; endprocedure; ! Eliminates extra whitespace and trailing punctuation from a string. ! ! Parameters: ! ! this_string String to be modified - input/output procedure eve$cleanse_string (this_string) if index ("\|", substr (this_string, length (this_string), 1)) > 0 then this_string := substr (this_string, 1, length (this_string) - 1); endif; edit (this_string, trim); endprocedure; ! Lookup a comment for a key, trimming any leading spaces which may be ! used by Eve to differentiate between Eve- and user-defined keys. ! Returns the string with the trimmed comment. ! ! Parameters: ! ! this_key ! Keyword of key to lookup - input procedure eve$lookup_comment (this_key) local key_comment; ! String containing key comment to be returned key_comment := lookup_key (this_key, comment); edit (key_comment, trim_leading); return (key_comment); endprocedure; ! Page 10 ! Prompts for a single key; returns the keyword for that key. ! ! Parameters: ! ! prompt Text of prompt - input procedure eve$prompt_key (prompt) local this_key; ! Keyword of key read after prompt map (eve$prompt_window, eve$prompt_buffer); erase (eve$prompt_buffer); position (end_of (eve$prompt_buffer)); copy_text (prompt); update (eve$prompt_window); this_key := read_key; if eve$lookup_comment (this_key) = "shift key" then this_key := eve$get_shift_key; endif; unmap (eve$prompt_window); return (this_key); endprocedure; ! Page 11 ! Procedure used by commands which prompt for integers. ! Returns true if prompting worked or was not needed, false otherwise. ! ! Parameters: ! ! old_number Old integer value - input ! new_number New integer value - output ! prompt_string Text of prompt - input ! no_value_message Message printed if user hits Return to ! get out of the command - input procedure eve$prompt_number (old_number, new_number, prompt_string, no_value_message) local read_line_string; ! String read after prompt new_number := old_number; if get_info(new_number, eve$kt_type) = string then if new_number = "" then new_number := eve$k_no_arg; else translate (new_number, "1", "l"); new_number := int(new_number); endif; endif; if new_number = eve$k_no_arg then read_line_string := read_line (prompt_string); eve$cleanse_string (read_line_string); if read_line_string = eve$kt_null then message (no_value_message); return (0); else translate (read_line_string, "1", "l"); new_number := int (read_line_string); if (new_number = 0) and (read_line_string <> "0") then message (fao ("Don't understand !AS", read_line_string)); return (0); else return (1); endif; endif; else return (1); endif; endprocedure; ! Page 12 ! Procedure used by commands which prompt for strings. ! Returns true if prompting worked or was not needed, false otherwise. ! ! Parameters: ! ! old_string Old string value - input ! new_string New string value - output ! prompt_string Text of prompt - input ! no_value_message Message printed if user hits Return to ! get out of the command - input procedure eve$prompt_string (old_string, new_string, prompt_string, no_value_message) local read_line_string; ! String read after prompt new_string := old_string; if old_string = eve$kt_null then new_string := read_line (prompt_string); if new_string = eve$kt_null then message (no_value_message); return (0); else return (1); endif; else return (1); endif; endprocedure; ! Page 13 ! Procedure to ensure that a change that inserts text before the ! top of the window displays the last line of the text on the ! first line of the window. procedure eve$show_first_line local old_position, ! Marker of position before scroll new_position; ! Marker of position after scroll update (current_window); if (get_info (current_window, eve$kt_current_row) = get_info (current_window, eve$kt_visible_top)) and (current_column = 1) then old_position := mark (none); scroll (current_window, -1); new_position := mark (none); ! Make sure we scrolled before doing the cursor_vertical if new_position <> old_position then cursor_vertical (1); endif; endif; endprocedure; ! Page 14 ! Move to a new position in the current window, putting the new position ! in the middle of the window by temporarily resetting the scrolling region. ! ! Parameters: ! ! new_position New cursor position - input procedure eve$position_in_middle (new_position) local scroll_offset, ! New value for scroll_top and scroll_bottom old_scroll_top, ! Original value of scroll_top old_scroll_bottom, ! Original value of scroll_bottom old_scroll_amount, ! Original value of scroll_amount this_window; ! Current window this_window := current_window; scroll_offset := (get_info (this_window, eve$kt_visible_length) / 2) - 2; if scroll_offset < 0 then scroll_offset := 0; else if scroll_offset > eve$x_max_scroll_offset then scroll_offset := eve$x_max_scroll_offset; endif; endif; old_scroll_top := get_info (this_window, "scroll_top"); old_scroll_bottom := get_info (this_window, "scroll_bottom"); old_scroll_amount := get_info (this_window, "scroll_amount"); set (scrolling, this_window, on, scroll_offset, scroll_offset, 0); position (new_position); update (this_window); set (scrolling, this_window, on, old_scroll_top, old_scroll_bottom, old_scroll_amount); endprocedure; ! Page 15 ! Procedures to help with choices for ambiguous names ! Take the result of an expand_name command, and put each of the choices on ! a separate line in the choice buffer. Erase any previous choices in the ! choice buffer. Cursor is left at beginning of choice buffer. ! ! Parameters: ! ! expanded_string Result of expand_name - input procedure eve$expand_to_choices (expanded_string) on_error if error = tpu$_strnotfound then position (beginning_of (eve$choice_buffer)); return; endif; endon_error; position (eve$choice_buffer); erase (eve$choice_buffer); if expanded_string = eve$kt_null then return; endif; copy_text (expanded_string); position (beginning_of (eve$choice_buffer)); ! Search for spaces, exit when you cannot find any more (through on_error) loop position (search (" ", forward, exact)); erase_character (1); split_line; endloop; endprocedure; ! Add a string on a new line in the choice buffer ! ! Parameters: ! ! choice_string String to add to choice buffer - input procedure eve$add_choice (choice_string) local this_buffer, ! Current buffer this_position; ! Current position in the buffer this_buffer := current_buffer; this_position := mark (none); position (end_of (eve$choice_buffer)); copy_text (choice_string); position (this_buffer); endprocedure; ! Page 16 ! Combines two tests: if there is only one item in the choice buffer, ! return that string as the choice. Otherwise, if the input string is ! an exact choice in the choice buffer, return the input string ! as the choice. If neither test is true, return the null string. ! Assume that cursor is at beginning of choice buffer (procedure is ! called after eve$expand_to_choices). ! ! Parameters: ! ! choice_string String to add to choice buffer - input procedure eve$get_choice (choice_string) on_error if error = tpu$_strnotfound then return (eve$kt_null); endif; endon_error; if get_info (eve$choice_buffer, eve$kt_record_count) <> 1 then position (search (line_begin & choice_string & line_end, forward, no_exact)); endif; return (current_line); endprocedure; ! Procedure to strip the first n characters off of the name of each ! choice in the choice buffer. Used for mark and command names. ! Leaves cursor at end of choice buffer. ! ! Parameters: ! ! how_much_to_strip Number of characters to strip - input procedure eve$strip_choices (how_much_to_strip) position (beginning_of (eve$choice_buffer)); loop exitif mark (none) = end_of (eve$choice_buffer); erase_character (how_much_to_strip); move_vertical (1); endloop; endprocedure; ! Page 17 ! Format the choice buffer (one choice per line) into nicely formatted ! columns. Assume that current position is in the choice buffer. procedure eve$format_choices local total_width, ! Screen width how_many_columns, ! Number of columns in display column_width, ! Width for each column which_column, ! Column index used during formatting leftover, ! Used in computation of column width string_position, ! Index into expanded_string which_item, ! String for current column entry how_many_items; ! How many items need to be formatted position (beginning_of (eve$choice_buffer)); how_many_items := get_info (eve$choice_buffer, eve$kt_record_count); if how_many_items = 0 then return; endif; loop exitif mark (none) = end_of (eve$choice_buffer); if column_width < length (current_line) then column_width := length (current_line); endif; move_vertical (1); endloop; total_width := get_info (eve$main_window, eve$kt_width); column_width := column_width + 2; how_many_columns := (total_width - 1) / column_width; if (how_many_columns * column_width) > total_width then ! rounded up how_many_columns := how_many_columns - 1; endif; if how_many_columns = 0 then how_many_columns := 1; else if how_many_items < how_many_columns then how_many_columns := how_many_items; column_width := (total_width - 1) / how_many_items; if (how_many_columns * column_width) > total_width then ! rounded up column_width := column_width - 1; endif; else loop leftover := (total_width - 1) - (how_many_columns * column_width); exitif leftover < how_many_columns; column_width := column_width + 1; endloop; endif; endif; which_column := 1; string_position := 1; position (beginning_of (eve$choice_buffer)); split_line; loop exitif mark (none) = end_of (eve$choice_buffer); which_item := erase_line; move_horizontal (-1); eve$capitalize_string (which_item); if (which_column = 1) and (column_width <= total_width) then copy_text (" "); endif; copy_text (which_item); if which_column = how_many_columns then if how_many_columns = 1 then eve$letter_wrap (0); endif; split_line; which_column := 1; else copy_text (substr (eve$kt_spaces, 1, column_width - length (which_item))); which_column := which_column + 1; endif; move_horizontal (1); endloop; if which_column > 1 then split_line; endif; endprocedure; ! Procedure to enable displaying of choices. ! ! Parameters: ! ! message_to_display ! Error message for message window - input procedure eve$display_choices (message_to_display) local this_buffer, ! Current buffer this_position; ! Marker for current cursor position this_buffer := current_buffer; this_position := mark (none); position (end_of (eve$choice_buffer)); eve$format_choices; eve$x_ambiguous_parse := 1; position (beginning_of (eve$choice_buffer)); position (this_buffer); message (message_to_display); endprocedure; ! Page 18 ! Letter-wrap the current line. ! ! Parameters: ! ! left_indent Number of spaces at start of continued ! line - input procedure eve$letter_wrap (left_indent) local wrap_width, ! Screen width this_position, ! Marker for current cursor position what_column; ! Current column wrap_width := get_info (current_window, eve$kt_width); this_position := mark (none); loop position (search (line_end, forward)); what_column := get_info (current_buffer, eve$kt_offset_column); exitif what_column <= wrap_width; move_horizontal (wrap_width - what_column); split_line; eve$to_column (left_indent); endloop; position (this_position); endprocedure; ! Page 19 ! Insert (not overstrike) spaces from current position until given column. ! If current offset greater than column, do nothing. ! ! Parameters: ! ! which_column Column to go to - input procedure eve$to_column (which_column) local this_buffer, ! Current buffer this_mode, ! Keyword for current mode distance; ! Number of spaces needed this_buffer := current_buffer; this_mode := get_info (this_buffer, eve$kt_mode); set (insert, this_buffer); loop distance := which_column - get_info (this_buffer, eve$kt_offset_column); exitif distance <= 0; if distance > length (eve$kt_spaces) then copy_text (eve$kt_spaces); else copy_text (substr (eve$kt_spaces, 1, distance)); endif; endloop; set (this_mode, this_buffer); endprocedure; ! Indent this line to the specified column, making using of existing whitespace ! Leave cursor at the specified column. ! ! Parameters: ! ! which_column ! Column to indent to - input procedure eve$indent_line_to (which_column) local this_position, ! Marker for current cursor position this_buffer; ! Current buffer this_buffer := current_buffer; move_horizontal (- current_offset); loop exitif get_info (this_buffer, eve$kt_offset_column) >= which_column; if (current_character = " ") or (current_character = ascii (9)) then move_horizontal (1); else exitif 1; endif; endloop; eve$to_column (which_column); endprocedure; ! Page 20 ! Procedures for trimming lines of extra whitespace ! Trim this line of extra spaces at end procedure eve$trim_line local eol_position, ! end of current line spaces_to_trim; ! number of spaces eol_position := search (line_end, forward); position (eol_position); loop exitif current_offset = 0; move_horizontal (-1); exitif index (eve$x_whitespace, current_character) = 0; spaces_to_trim := spaces_to_trim + 1; endloop; position (eol_position); erase_character (- spaces_to_trim); endprocedure; ! Trim each line in a buffer. Only trim spaces, not other whitespace. ! ! Parameters: ! ! trim_buffer Buffer to trim - input procedure eve$trim_buffer (trim_buffer) local this_position, ! Marker for current cursor position this_buffer, ! Current buffer trim_range; ! Range with trailing spaces on_error if error = tpu$_strnotfound then trim_range := 0; endif; endon_error; this_position := mark (none); this_buffer := current_buffer; position (beginning_of (trim_buffer)); loop trim_range := search (eve$pattern_trim, forward); exitif trim_range = 0; position (beginning_of (trim_range)); erase_character (length (trim_range)); endloop; position (trim_buffer); position (this_position); endprocedure; ! Page 21 ! Set status line of a window to include buffer name and mode indications. ! Used primarily to indicate insert/overstrike and forward/reverse toggling. ! ! Parameters: ! ! this_window Window whose status line is being set - input procedure eve$set_status_line (this_window) local this_buffer, ! Current buffer mode_string, ! String version of current mode direction_string, ! String version of current direction buffer_name; ! String containing name of current buffer this_buffer := get_info (this_window, eve$kt_buffer); ! Don't add a status line to windows without a status line if (this_buffer = 0) or (get_info (this_window, "status_line") = 0) then return; endif; if get_info (this_buffer, eve$kt_mode) = insert then mode_string := "Insert "; else mode_string := "Overstrike"; endif; if get_info (this_buffer, "direction") = reverse then direction_string := "Reverse"; else direction_string := "Forward"; endif; buffer_name := get_info (this_buffer, eve$kt_name); if length (buffer_name) > eve$x_max_buffer_name_length then buffer_name := substr (buffer_name, 1, eve$x_max_buffer_name_length); else buffer_name := buffer_name + substr (eve$kt_spaces, 1, eve$x_max_buffer_name_length - length (buffer_name)); endif; set (status_line, this_window, reverse, " Buffer " + buffer_name + " " + mode_string + " " + direction_string); endprocedure; ! Page 22 ! Update the status line in all windows mapped to the current buffer procedure eve$update_status_lines local this_buffer, ! Current buffer loop_window; ! Window currently being checked in loop this_buffer := current_buffer; if get_info (this_buffer, "map_count") > 1 then loop_window := get_info (window, eve$kt_first); loop exitif loop_window = 0; if get_info (loop_window, eve$kt_buffer) = this_buffer then eve$set_status_line (loop_window); endif; loop_window := get_info (window, "next"); endloop; else eve$set_status_line (current_window); endif; endprocedure; ! procedure to get a yes/no answer. A null answer defulats to "yes", ! otherwise the answer must be either "yes" or "no" or and abbreviation ! thereof. procedure eve$insist_y_n (the_prompt) local original_reply, ! String returned by read_line after prompt lower_reply; ! Lowercase version of original_reply ! Loop until we get a yes/no reply (or just CR for yes) loop lower_reply := read_line (the_prompt); original_reply := lower_reply; change_case (lower_reply, lower); if (length (lower_reply) = 0) or (lower_reply = substr ("yes", 1, length (lower_reply))) then return (TRUE); else if lower_reply = substr ("no", 1, length (lower_reply)) then return (FALSE); else message (fao ("Don't understand !AS;", original_reply) + " please answer yes or no"); endif; endif; endloop; endprocedure ! Page 23 ! Toggle direction between forward and reverse procedure eve_change_direction ! Keypad commands if current_direction = forward then set (reverse, current_buffer); else set (forward, current_buffer); endif; eve$update_status_lines; endprocedure; ! Toggle mode between insert and overstrike procedure eve_change_mode if get_info (current_buffer, eve$kt_mode) = overstrike then set (insert, current_buffer); else set (overstrike, current_buffer); endif; eve$update_status_lines; endprocedure; ! Page 24 ! Delete previous character procedure eve_delete local this_position; ! Marker for current cursor position ! If we don't mark this position now we'll get funny results later ! if cursor is beyond end of line this_position := mark (none); if current_window = eve$command_window then if get_info (current_buffer, eve$kt_offset_column) <= (eve$x_command_prompt_length + 1) then return; endif; endif; if get_info (current_buffer, eve$kt_offset_column) <= get_info (current_buffer, eve$kt_left_margin) then eve$append_line; else if get_info (current_buffer, eve$kt_mode) = insert then erase_character (-1); else if current_character = eve$kt_null then erase_character (-1); else move_horizontal (-1); if current_character <> ascii (9) then copy_text (" "); move_horizontal (-1); else erase_character (1); endif; endif; endif; endif; endprocedure; ! Page 25 ! Erase next word procedure eve_erase_word local this_buffer, ! Current buffer this_mode, ! Keyword for current mode temp_string, ! String used to check for start of line start_erase_word, ! Marker for beginning of previous word end_erase_word, ! Marker for end of previous word spaces_to_erase, ! Number of between-word spaces to erase erase_word_range; ! Range for previous word if current_window = eve$command_window then eve_erase_previous_word; return; endif; this_buffer := current_buffer; if mark (none) = end_of (this_buffer) then return; endif; ! Are we on a space between words? If so, compress whitespace and ! move to start of next word. if index (eve$x_whitespace, current_character) <> 0 then eve$compress_whitespace; endif; ! Check for end of line if current_character = eve$kt_null then if current_offset = 0 then temp_string := ascii (10); else move_horizontal (-1); temp_string := current_character; move_horizontal (1); endif; move_horizontal (1); eve$append_line; if mark (none) <> end_of (this_buffer) then if index (eve$x_word_separators, temp_string) = 0 then this_mode := get_info (this_buffer, eve$kt_mode); set (insert, this_buffer); copy_text (" "); set (this_mode, this_buffer); endif; endif; eve$x_restoring_line := 1; eve$x_restore_text := eve$kt_null; else if not eve$at_start_of_word then eve$start_of_word; endif; start_erase_word := mark (none); eve$end_of_word; move_horizontal (-1); end_erase_word := mark (none); erase_word_range := create_range (start_erase_word, end_erase_word, none); position (start_erase_word); eve$x_restore_text := erase_character (length (erase_word_range)); eve$x_restoring_line := 0; endif; endprocedure; ! Page 26 ! Delete all whitespace surrounding the current character, except for ! the first whitespace character (delete that too if at start of line). ! Position cursor at beginning of next word. No-op if current character ! is not whitespace. Trim spaces if at end of line. procedure eve$compress_whitespace if current_character = eve$kt_null then eve$trim_line; return; endif; if index (eve$x_whitespace, current_character) = 0 then return; endif; loop exitif current_offset = 0; move_horizontal (-1); if index (eve$x_whitespace, current_character) = 0 then move_horizontal (2); ! leave first whitespace if not at start of line exitif 1; endif; endloop; if index (eve$x_whitespace, current_character) <> 0 then erase (search (eve$pattern_whitespace, forward)); endif; endprocedure; ! Page 27 ! Exit Eve. Write the current buffer if modified, and ask the user ! about writing out any other modified buffers. procedure eve_exit local exit_buffer, ! Current buffer being checked for writing exit_buffer_name; ! String with name of exit_buffer on_error ! Lots of different errors possible from write_file, doesn't matter here set (success, on); message (fao ("Will not exit; could not write buffer !AS", exit_buffer_name)); return; endon_error; message (eve$kt_null); exit_buffer_name := eve$kt_null; exit_buffer := current_buffer; if (get_info (exit_buffer, "modified")) and (not (get_info (exit_buffer, "no_write"))) then if eve$x_trimming then message ("Trimming buffer..."); eve$trim_buffer (exit_buffer); message ("Trimming completed"); endif; write_file (exit_buffer); set (no_write, exit_buffer); endif; exit_buffer := get_info (buffers, eve$kt_first); loop exitif exit_buffer = 0; if (get_info (exit_buffer, "modified")) and (not (get_info (exit_buffer, "no_write"))) then exit_buffer_name := substr (get_info (exit_buffer, eve$kt_name), 1, eve$x_max_buffer_name_length); if eve$insist_y_n (fao ("Write buffer !AS? ", exit_buffer_name)) then if eve$x_trimming then message ("Trimming buffer..."); eve$trim_buffer (exit_buffer); message ("Trimming completed"); endif; write_file (exit_buffer); endif; set (no_write, exit_buffer); endif; exit_buffer := get_info (buffers, "next"); endloop; ! Avoid "editor successfully exiting" message - on_error will restore ! success messages set (success, off); exit; endprocedure; ! Page 28 ! Top-level find command. Calls eve$find, as does the replace command. ! The two commands have slightly different requirements, so they both ! call eve$find and pass it a parameter to indicate the caller. ! ! Parameters: ! ! target String to find - input procedure eve_find (target) eve$find (target, 0); endprocedure; ! Page 29 ! Search for target in the current direction. If not found in the ! current direction look in the opposite direction, but do not go ! there without prompting the user. Search is case-insensitive if ! target is all lowercase; otherwise is case-sensitive. ! Returns range if target found, otherwise returns false. ! ! Parameters: ! ! target String to find - input ! replacing If true, called by eve_replace; allow a ! match at current cursor position - input procedure eve$find (target, replacing) local new_target, ! Local copy of target lowercase_target, ! Lowercase version of eve$x_target start_find_key, ! String describing key used to invoke find stop_find_key, ! String describing key used after prompt this_position, ! Marker for current cursor position how_exact, ! Keyword to indicate case-sensitivity find_range, ! Range returned by search other_direction, ! Keyword for opposite direction other_direction_string, ! String for message including other_direction find_reply, ! Reply to inquiry about changing direction change_direction_key; ! Keyword for key used to end find_reply on_error if error = tpu$_strnotfound then find_range := 0; endif; endon_error; start_find_key := eve$lookup_comment (last_key); if target <> eve$kt_null then new_target := target; else if current_direction = forward then new_target := read_line ("Forward Find: "); else new_target := read_line ("Reverse Find: "); endif; endif; stop_find_key := eve$lookup_comment (last_key); if new_target = eve$kt_null then if (start_find_key = "find") and (stop_find_key = "find") then if eve$x_target = eve$kt_null then message ("No previous target to find"); return (0); else if get_info (eve$x_target, eve$kt_type) = string then message (fao ("Finding previous target: !AS", eve$x_target)); else message ("Finding previous target: "); endif; endif; else message ("Nothing to find"); return (0); endif; else eve$x_target := new_target; endif; lowercase_target := eve$x_target; if get_info (lowercase_target, eve$kt_type) = string then change_case (lowercase_target, lower); endif; if lowercase_target = eve$x_target then how_exact := no_exact; else how_exact := exact; endif; this_position := mark (none); if current_direction = forward then if this_position <> end_of (current_buffer) then if not replacing then move_horizontal (1); endif; find_range := search (eve$x_target, forward, how_exact); else find_range := 0; endif; else if this_position <> beginning_of (current_buffer) then move_horizontal (-1); find_range := search (eve$x_target, reverse, how_exact); else find_range := 0; endif; endif; if find_range = 0 then if current_direction = forward then other_direction := reverse; other_direction_string := "reverse"; else other_direction := forward; other_direction_string := "forward"; endif; position (this_position); if other_direction = forward then if this_position <> end_of (current_buffer) then move_horizontal (1); find_range := search (eve$x_target, forward, how_exact); else find_range := 0; endif; else if this_position <> beginning_of (current_buffer) then move_horizontal (-1); find_range := search (eve$x_target, reverse, how_exact); else find_range := 0; endif; endif; if find_range = 0 then if get_info (eve$x_target, eve$kt_type) = string then message (fao ("Could not find: !AS", eve$x_target)); else message ("Could not find: "); endif; position (this_position); return (0); else find_reply := read_line (fao ("Found in !AS direction. Go there? ", other_direction_string)); ! Hitting return or do means yes; hitting another non-typing ! key is probably a mistake, so interpret as no. if find_reply = eve$kt_null then change_direction_key := eve$lookup_comment (last_key); if (change_direction_key = "return") or (change_direction_key = "do") then find_reply := "yes"; else find_reply := "no"; endif; else change_case (find_reply, lower); endif; if substr ("yes", 1, length (find_reply)) = find_reply then set (other_direction, current_buffer); eve$update_status_lines; eve$position_in_middle (beginning_of (find_range)); return (find_range); else position (this_position); return (0); endif; endif; else eve$position_in_middle (beginning_of (find_range)); return (find_range); endif; endprocedure; ! Page 30 ! Top-level help command. Calls eve$help_keypad for keypad help, ! otherwise provides help on Eve commands. ! ! Parameters: ! ! first_topic String containing topic from command ! line - input procedure eve_help (first_topic) local this_topic, ! Topic name as typed by user lowercase_topic, ! Lowercase version of this_topic last_key_name, ! Keyword for last key after help prompt expand_result, ! String of possible Eve commands this_window, ! Current window showing_commands; ! True if showing Eve command list if current_window = info_window then unmap (info_window); position (eve$x_this_window); endif; this_window := current_window; this_topic := first_topic; map (info_window, help_buffer); last_key_name := "return"; message (eve$kt_null); loop eve$cleanse_string (this_topic); lowercase_topic := this_topic; change_case (lowercase_topic, lower); if lowercase_topic = "keypad" then eve$help_keypad; exitif 1; endif; if (last_key_name = "next_screen") or (last_key_name = "previous_screen") then execute (lookup_key (last_key, program)); update (info_window); else if (lowercase_topic = eve$kt_null) or (lowercase_topic = "?") or (lowercase_topic = "commands") then message (eve$kt_null); this_topic := "eve commands"; else expand_result := eve$parse (this_topic); if expand_result = eve$kt_null then this_topic := "eve commands"; else if index (expand_result, "(") = 0 then expand_result := substr (expand_result, 5, length (expand_result)); else expand_result := substr (expand_result, 5, index (expand_result, "(") - 5); endif; this_topic := "eve " + expand_result; endif; endif; if this_topic = "eve commands" then set (status_line, info_window, reverse, " Help buffer Press Next Screen or Prev Screen to see other commands"); if not showing_commands then eve$help_text (this_topic); endif; showing_commands := 1; else set (status_line, info_window, reverse, " Help buffer"); eve$help_text (this_topic); showing_commands := 0; endif; endif; if showing_commands then this_topic := read_line ("Type command you want help on (press Return if done): "); else this_topic := read_line ("Type command name, or ? for list (press Return if done): "); endif; eve$cleanse_string (this_topic); if this_topic = eve$kt_null then last_key_name := eve$lookup_comment (last_key); if (expand_result = "tpu") and (last_key_name = "do") then help_text ("tpuhelp", "vaxtpu", on, help_buffer); exitif 1; else exitif (last_key_name = "return") or (last_key_name = "do") or (last_key_name = "exit"); endif; else last_key_name := "return"; endif; endloop; unmap (info_window); position (this_window); eve$x_ambiguous_parse := 0; message (eve$kt_null); endprocedure; ! Page 31 ! Do help_text for a given topic, stripping librarian header information, ! and update the info_window. ! ! Parameters: ! ! topic String containing topic for VMS ! librarian - input procedure eve$help_text (topic) local this_range; ! Range to check for white-space on_error ! Invalid topic, do our best update (info_window); return; endon_error; help_text ("tpuhelp", topic, off, help_buffer); position (beginning_of (help_buffer)); move_vertical (5); this_range := search (eve$pattern_whitespace, forward); ! error if not found if length (this_range) > 4 then ! allow indentation if desired move_horizontal (3); else move_horizontal (length (this_range) - 1); endif; erase (create_range (beginning_of (help_buffer), mark (none), none)); update (info_window); endprocedure; ! Page 32 ! Procedure to display keypad-oriented help. Called by eve_help. procedure eve$help_keypad local help_char, ! Keyword of key to provide help on which_topic, ! String with help library subtopic showing_keypad, ! True if currently displaying keypad diagram to_be_ignored; ! Key-name of the stroke to be ignored which_topic := eve$kt_null; set (status_line, info_window, reverse, " Help buffer"); if eve$x_vt200_keypad then eve$help_text ("keypad_diagrams eve_vt200"); else eve$help_text ("keypad_diagrams eve_vt100"); endif; showing_keypad := 1; loop if showing_keypad then help_char := eve$prompt_key ("Press key that you want help on (Return to leave help): "); else help_char := eve$prompt_key ("Press key that you want help on (Help for keypad, Return to leave help): "); endif; if help_char = to_be_ignored then to_be_ignored := FALSE; else which_topic := eve$lookup_comment (help_char); exitif which_topic = "return"; if which_topic = eve$kt_null then if eve$alphabetic (help_char) <> eve$kt_null then which_topic := "typing"; else which_topic := "unknown"; endif; endif; if (which_topic = "help") and (not showing_keypad) then if eve$x_vt200_keypad then eve$help_text ("keypad_diagrams eve_vt200"); else eve$help_text ("keypad_diagrams eve_vt100"); endif; showing_keypad := 1; else eve$help_text ("eve " + which_topic); showing_keypad := 0; endif; endif; endloop; endprocedure; ! Page 33 ! Move to start of line if current direction is reverse; ! else move to end of line. If this would be a no-op, go ! to the start of the previous line or the end of the next line. procedure eve_move_by_line local beyond_eol; ! True if cursor beyond end of current line on_error return; endon_error; beyond_eol := get_info (current_window, eve$kt_beyond_eol); if current_direction = reverse then if not beyond_eol then if current_offset = 0 then move_vertical (-1); endif; endif; position (search (line_begin, reverse)); ! In command buffer, don't back up beyond prompt if current_buffer = eve$command_buffer then if substr (current_line, 1, eve$x_command_prompt_length) = eve$x_command_prompt then move_horizontal (eve$x_command_prompt_length); endif; endif; else if beyond_eol then position (search (line_begin, reverse)); update (current_window); move_vertical (1); else if current_character = eve$kt_null then move_vertical (1); endif; endif; position (search (line_end, forward)); endif; endprocedure; ! Page 34 ! Cursor motion procedures ! Move down one row, staying in the same column. Scroll if necessary. procedure eve_move_down if get_info (current_window, eve$kt_current_row) = get_info (current_window, "visible_bottom") then scroll (current_window, 1); else cursor_vertical (1); endif; endprocedure; ! Move left one column. Do not wrap at edge of the screen. procedure eve_move_left cursor_horizontal (-1); endprocedure; ! Move right one column. Do not wrap at edge of the screen. procedure eve_move_right cursor_horizontal (1); endprocedure; ! Move up one row, staying in the same column. Scroll if necessary. procedure eve_move_up if get_info (current_window, eve$kt_current_row) = get_info (current_window, eve$kt_visible_top) then scroll (current_window, -1); else cursor_vertical (-1); endif; endprocedure; ! Page 35 ! Scroll forward one screen procedure eve_next_screen eve$move_by_screen (1); endprocedure; ! Scroll back one screen procedure eve_previous_screen eve$move_by_screen (-1); endprocedure; ! Page 36 ! Procedure to move by screen - used by eve_next_screen and eve_previous_screen ! Positive numbers move forward (like next screen), negative numbers backward ! Returns false if an error is encountered; otherwise returns true. ! ! Parameters: ! ! how_many_screens Number of screens to move - input procedure eve$move_by_screen (how_many_screens) local how_much_scroll, ! How many lines to scroll scroll_window, ! Window to be scrolled this_window, ! Current window this_column, ! Current column in scroll_window this_row, ! Current row in scroll_window old_scroll_top, ! Original value of scroll_top old_scroll_bottom, ! Original value of scroll_bottom old_scroll_amount; ! Original value of scroll_amount ! Trap and ignore messages about move beyond buffer boundaries - ! just move to top or bottom line of buffer on_error eve$move_by_screen := 0; ! and continue endon_error; eve$move_by_screen := 1; this_window := current_window; if this_window = eve$command_window then if eve$x_ambiguous_parse then scroll_window := eve$choice_window; else scroll_window := eve$x_pre_command_window; endif; position (scroll_window); else scroll_window := this_window; endif; how_much_scroll := get_info (scroll_window, eve$kt_visible_length); if get_info (scroll_window, "status_line") <> eve$kt_null then how_much_scroll := how_much_scroll - 3; else how_much_scroll := how_much_scroll - 2; endif; if how_much_scroll <= 0 then how_much_scroll := 1; endif; ! By using a scrolling region and move_vertical, we can move to the first or ! last line on the screen when on the first or last screen in the buffer. Also ! is much faster for scrolling a select range than using the scroll builtin. this_row := get_info (scroll_window, eve$kt_current_row); if this_row = 0 then ! Screen info not all updated yet this_row := get_info (scroll_window, eve$kt_visible_top); endif; this_column := get_info (scroll_window, "current_column"); position (search (line_begin, reverse)); if get_info (scroll_window, eve$kt_beyond_eol) then update (scroll_window); endif; old_scroll_top := get_info (scroll_window, "scroll_top"); old_scroll_bottom := get_info (scroll_window, "scroll_bottom"); old_scroll_amount := get_info (scroll_window, "scroll_amount"); set (scrolling, scroll_window, on, this_row - get_info (scroll_window, eve$kt_visible_top), get_info (scroll_window, "visible_bottom") - this_row, 0); move_vertical (how_many_screens * how_much_scroll); update (scroll_window); cursor_horizontal (this_column - get_info (scroll_window, "current_column")); if this_window <> current_window then position (this_window); endif; set (scrolling, scroll_window, on, old_scroll_top, old_scroll_bottom, old_scroll_amount); endprocedure; ! Page 37 ! Procedure invoked by the Return key. Split the current line, ! obeying margin settings. procedure eve_return local left_margin; ! Left margin of current buffer if current_window = eve$command_window then eve$exit_command_window; else if get_info (current_buffer, eve$kt_offset_column) > get_info (current_buffer, eve$kt_right_margin) then eve$fill_line (0); else eve$split_line; endif; eve$show_first_line; left_margin := get_info (current_buffer, eve$kt_left_margin); if left_margin > 1 then eve$to_column (left_margin); endif; endif; endprocedure; ! Provides a hook for user-written procedures such as auto-indent. procedure eve$split_line split_line; endprocedure; ! Page 38 ! Start a select region procedure eve_select if eve$x_select_position <> 0 then eve$x_select_position := 0; message ("Selection cancelled."); else message ("Selection started. Press Remove when finished."); eve$x_select_position := select (eve$x_highlighting); endif; endprocedure; ! Page 39 ! Cut (Remove) and Paste (Insert Here) procedures ! Move the select region to the insert here buffer procedure eve_remove local this_position, ! Marker for current cursor position remove_range; ! Range being removed this_position := mark (none); if eve$x_select_position <> 0 then if get_info (eve$x_select_position, eve$kt_buffer) <> current_buffer then message ("Remove must be used in the same buffer as Select."); else remove_range := select_range; ! Select & Remove in same spot => erase this character if remove_range = 0 then if this_position = end_of (current_buffer) then message ("Nothing to remove"); eve$x_select_position := 0; return; else remove_range := create_range (mark (none), mark (none), none); endif; endif; erase (paste_buffer); position (paste_buffer); split_line; move_vertical (-1); move_text (remove_range); position (this_position); eve$x_select_position := 0; remove_range := 0; message ("Remove completed."); endif; else message ("Use Select before using Remove."); endif; endprocedure; ! Page 40 ! Copy contents of insert here buffer before current cursor position procedure eve_insert_here local this_mode; ! Keyword for current mode if beginning_of (paste_buffer) <> end_of (paste_buffer) then this_mode := get_info (current_buffer, eve$kt_mode); set (insert, current_buffer); copy_text (paste_buffer); append_line; ! did a split_line during eve_remove set (this_mode, current_buffer); eve$show_first_line; else if eve$x_select_position <> 0 then message ("Nothing to insert. Use Remove to select a range of text."); else message ("Nothing to insert. Use Select to select a range of text."); endif; endif; endprocedure; ! Page 41 ! Procedure bound to the space bar. Inserts a space and does word wrap ! based on the margin settings. procedure eve_space eve$fill_line (1); endprocedure; ! Page 42 ! Word-wrap procedure. ! ! Parameters: ! ! insert_space If true, insert a space at the end of the ! filled line - input procedure eve$fill_line (insert_space) local this_buffer, ! Current buffer left_margin, ! Left margin of this_buffer right_margin, ! Right margin of this_buffer space_position, ! Marker for current cursor position this_column, ! Current column hot_column, ! Column at start of hot zone words, ! Number of words in hot zone line_position, ! Previous position in current line spaces, ! Number of spaces between words start_of_line; ! Column at start of new line this_buffer := current_buffer; left_margin := get_info (this_buffer, eve$kt_left_margin); right_margin := get_info (this_buffer, eve$kt_right_margin); if (right_margin - left_margin) <= eve$x_hot_zone_size then hot_column := right_margin; else hot_column := right_margin - eve$x_hot_zone_size; endif; space_position := mark (none); this_column := get_info (this_buffer, eve$kt_offset_column); if (this_column <= hot_column) or (this_buffer = eve$command_buffer) then if insert_space then copy_text (" "); endif; return; endif; right_margin := right_margin + 1; line_position := mark (none); loop this_column := get_info (this_buffer, eve$kt_offset_column); exitif this_column <= right_margin; line_position := mark (none); spaces := 0; exitif eve$start_of_word = 0; spaces := eve$backup_over_whitespace; words := words + 1; endloop; ! No sense splitting at the beginning of the line this_column := get_info (this_buffer, eve$kt_offset_column); if this_column = left_margin then position (line_position); endif; erase_character (spaces); eve$split_line; if left_margin > 1 then eve$to_column (left_margin); endif; start_of_line := get_info (this_buffer, eve$kt_offset_column); position (space_position); this_column := get_info (this_buffer, eve$kt_offset_column); if this_column > right_margin then if words > 1 then eve$fill_line (insert_space); else eve$split_line; if left_margin > 1 then eve$to_column (left_margin); endif; endif; else if insert_space and (this_column <> start_of_line) then copy_text (" "); endif; endif; endprocedure; ! Page 43 ! Backup over whitespace. Return number of spaces. procedure eve$backup_over_whitespace local temp_length; ! Number of characters backed up over if current_offset = 0 then return (0); endif; temp_length := 0; loop ! Back up past whitespace move_horizontal (-1); if index (eve$x_whitespace, current_character) <> 0 then temp_length := temp_length + 1; exitif current_offset = 0; else move_horizontal (1); exitif 1; endif; endloop; return (temp_length); endprocedure; ! Page 44 ! Tab key procedure. Always inserts a tab, even if current mode is overstrike. procedure eve_tab local this_mode; ! Keyword for current mode this_mode := get_info (current_buffer, eve$kt_mode); set (insert, current_buffer); copy_text (ascii (9)); set (this_mode, current_buffer); endprocedure; ! Page 45 ! Go to end of the current buffer procedure eve_bottom ! Editing commands if mark (none) = end_of (current_buffer) then message ("Already at bottom"); else position (end_of (current_buffer)); endif; endprocedure; ! Go to beginning of the current buffer procedure eve_top if mark (none) = beginning_of (current_buffer) then message ("Already at top"); else position (beginning_of (current_buffer)); endif; endprocedure; ! Page 46 ! Capitalize first letter, put rest of word in lowercase. procedure eve_capitalize_word local word_range, ! Range for current word word_string, ! String for current word this_mode; ! Current mode for this buffer word_range := eve$current_word; if (word_range <> 0) and (current_offset > 0) then word_string := erase_character (- length (word_range)); eve$capitalize_string (word_string); this_mode := get_info (current_buffer, eve$kt_mode); set (insert, current_buffer); copy_text (word_string); set (this_mode, current_buffer); endif; endprocedure; ! Page 47 ! Center the current line between the margins procedure eve_center_line local this_position, ! Marker for current cursor position count, ! Number of spaces to erase at start of line left_margin, ! Left margin for current buffer right_margin, ! Right margin for current buffer width_of_screen, ! Screen width this_column; ! Current column this_position := mark (none); if this_position = end_of (current_buffer) then return; endif; move_horizontal (- current_offset); loop exitif current_character = eve$kt_null; exitif index (eve$x_whitespace, current_character) = 0; count := count + 1; move_horizontal (1); endloop; erase_character (- count); ! Too much pain to keep a count here, just delete a character at a time position (search (line_end, forward)); loop exitif current_offset = 0; move_horizontal (-1); exitif index (eve$x_whitespace, current_character) = 0; erase_character (1); endloop; left_margin := get_info (current_buffer, eve$kt_left_margin); right_margin := get_info (current_buffer, eve$kt_right_margin); width_of_screen := get_info (current_window, eve$kt_width); if right_margin > width_of_screen then right_margin := width_of_screen; endif; ! How much whitespace to insert this_column := get_info (current_buffer, eve$kt_offset_column); count := (((right_margin - left_margin) - this_column) / 2) + left_margin; eve$indent_line_to (count); position (this_position); endprocedure; ! Page 48 ! Go to the end of the current line. ! Display a message if already at the end of this line. procedure eve_end_of_line if get_info (current_window, eve$kt_beyond_eol) then position (search (line_begin, reverse)); endif; if mark (none) = end_of (current_buffer) then message ("Already at end of line") else if current_character = eve$kt_null then message ("Already at end of line"); else position (search (line_end, forward)); endif; endif; endprocedure; ! Page 49 ! Delete current character procedure eve_erase_character local this_position; ! Marker for current cursor position this_position := mark (none); if this_position = end_of (current_buffer) then return; else if current_character = eve$kt_null then move_horizontal (1); if mark (none) = end_of (current_buffer) then move_horizontal (-1); else eve$append_line; endif; else if get_info (current_buffer, eve$kt_mode) = overstrike then copy_text (" "); else erase_character (1); endif; endif; endif; endprocedure; ! Page 50 ! Erase from current position through end of line, including eol character procedure eve_erase_line eve$x_restoring_line := 1; if current_offset = 0 then eve$x_restore_text := erase_line; else ! Erase_character stops deleting at the end of the line eve$x_restore_text := erase_character (length (current_line)); move_horizontal (- current_offset); move_vertical (1); if mark (none) = end_of (current_buffer) then move_horizontal (-1); else eve$append_line; endif; endif; endprocedure; ! Page 51 ! Erase a word. If at start of word (or preceding character is blank), ! erase preceding word; else erase current word. procedure eve_erase_previous_word local this_buffer, ! Current buffer this_mode, ! Keyword for current mode temp_string, ! String used to check for start of line start_erase_word, ! Marker for beginning of previous word end_erase_word, ! Marker for end of previous word erase_word_range; ! Range for previous word this_buffer := current_buffer; if current_window = eve$command_window then if get_info (this_buffer, eve$kt_offset_column) <= (eve$x_command_prompt_length + 1) then return; endif; endif; if get_info (this_buffer, eve$kt_offset_column) <= get_info (this_buffer, eve$kt_left_margin) then if mark (none) <> beginning_of (this_buffer) then if (eve$append_line) then if current_offset = 0 then temp_string := ascii (10); else move_horizontal (-1); temp_string := current_character; move_horizontal (1); endif; if index (eve$x_word_separators, temp_string) = 0 then this_mode := get_info (this_buffer, eve$kt_mode); set (insert, this_buffer); copy_text (" "); set (this_mode, this_buffer); endif; eve$x_restoring_line := 1; eve$x_restore_text := eve$kt_null; return; endif; else return; endif; endif; eve$start_of_word; start_erase_word := mark (none); eve$end_of_word; move_horizontal (-1); ! don't want first character of next word end_erase_word := mark (none); erase_word_range := create_range (start_erase_word, end_erase_word, none); position (start_erase_word); eve$x_restore_text := erase_character (length (erase_word_range)); eve$x_restoring_line := 0; endprocedure; ! Page 52 ! Erase from current cursor position to start of line. ! For CTRL/U compatibility. procedure eve_erase_start_of_line local erase_length; ! How much of current line to erase if mark (none) = end_of (current_buffer) then return; endif; erase_length := current_offset; if current_buffer = eve$command_buffer then if substr (current_line, 1, eve$x_command_prompt_length) = eve$x_command_prompt then erase_length := current_offset - eve$x_command_prompt_length; endif; if erase_length > 0 then eve$x_restore_text := erase_character (- erase_length); eve$x_restoring_line := 0; endif; else eve$x_restore_text := erase_character (- erase_length); eve$x_restoring_line := 0; eve$indent_line_to (get_info (current_buffer, eve$kt_left_margin)); endif; endprocedure; ! Page 53 ! Fills the current paragraph procedure eve_fill_paragraph local this_position, ! Marker for current cursor position start_paragraph, ! Marker for start of current paragraph stop_paragraph, ! Marker for end of current paragraph fill_range; ! Range for current paragraph ! Can't fill an empty buffer - avoid additional checks later on if beginning_of (current_buffer) = end_of (current_buffer) then message ("Nothing to fill"); return; endif; this_position := mark (none); ! Find beginning and end of paragraph ! If on a blank line do preceding paragraph move_horizontal (- current_offset); loop exitif mark (none) = beginning_of (current_buffer); move_vertical (-1); if eve$paragraph_break then move_vertical (1); exitif 1; endif; endloop; start_paragraph := mark (none); position (this_position); move_horizontal (- current_offset); loop exitif mark (none) = end_of (current_buffer); exitif eve$paragraph_break; move_vertical (1); endloop; if start_paragraph = mark (none) then message ("Nothing to fill"); position (this_position); else move_horizontal (-1); stop_paragraph := mark (none); ! Now fill the paragraph fill_range := create_range (start_paragraph, stop_paragraph, none); fill (fill_range, eve$x_fill_separators); position (stop_paragraph); eve$show_first_line; endif; endprocedure; ! Page 54 ! Returns true if current line looks like a runoff command (starts with ! a period followed by an alphabetic character) or a blank line, ! else returns false. Assumes cursor was at start of line. procedure eve$paragraph_break on_error return (0); endon_error; if search (eve$pattern_paragraph_break, forward) <> 0 then return (1); endif; endprocedure; ! Page 55 ! Change direction to forward procedure eve_forward set (forward, current_buffer); eve$update_status_lines; endprocedure; ! Change direction to reverse procedure eve_reverse set (reverse, current_buffer); eve$update_status_lines; endprocedure; ! Page 56 ! Go to a mark. If mark is in a different buffer, map that ! buffer to the screen, and if there are two windows, map ! the new buffer to the other window. ! ! Parameters: ! ! go_to_parameter String containing mark name - input procedure eve_go_to (go_to_parameter) local mark_name, ! Local copy of go_to_parameter full_mark_name, ! Full mark name, including eve$mark_ prefix expanded_string, ! String of all expansions of full_mark_name this_choice, ! Current item in expanded_string possible_mark_names, ! Expanded_string without eve$mark_ prefixes mark_index, ! Index into expanded_string actual_mark, ! Complete name, with prefix, of mark to go to this_buffer, ! Current buffer this_position, ! Marker for current cursor position message_mark; ! Actual_mark without prefix and in lowercase on_error if error = tpu$_nonames then message (fao ("Mark !AS not set", mark_name)); return; endif; endon_error; if not (eve$prompt_string (go_to_parameter, mark_name, "Go to: ", "No mark name given")) then return; endif; eve$cleanse_string (mark_name); full_mark_name := "eve$mark_" + mark_name; change_case (full_mark_name, upper); expanded_string := expand_name (full_mark_name, variables); this_buffer := current_buffer; this_position := mark (none); eve$expand_to_choices (expanded_string); actual_mark := eve$get_choice (full_mark_name); eve$strip_choices (9); position (this_buffer); if actual_mark <> eve$kt_null then ! Execute can only handle 132-character strings, so mark can only be ! 82 characters long (41 chars here, + eve$mark_) - same thing in show execute ("eve$x_buffer_of_mark:=get_info(" + actual_mark + ",eve$kt_buffer)"); if eve$x_buffer_of_mark <> current_buffer then if eve$check_bad_window then message ("Cursor has been moved to a text window; try command again"); return; endif; if eve$x_number_of_windows = 2 then if current_window = eve$top_window then position (eve$bottom_window); else position (eve$top_window); endif; endif; if eve$x_buffer_of_mark <> current_buffer then map (current_window, eve$x_buffer_of_mark); eve$set_status_line (current_window); endif; endif; execute ("eve$position_in_middle (" + actual_mark + ")"); message_mark := substr (actual_mark, 10, length (actual_mark)); change_case (message_mark, lower); message (fao ("Going to mark !AS", message_mark)); else eve$display_choices (fao ("Ambiguous mark name: !AS", mark_name)); endif; endprocedure; ! Page 57 ! Change to insert mode procedure eve_insert_mode set (insert, current_buffer); eve$update_status_lines; endprocedure; ! Change to overstrike mode procedure eve_overstrike_mode set (overstrike, current_buffer); eve$update_status_lines; endprocedure; ! Page 58 ! Go to start of a certain line in the current buffer ! ! Parameters: ! ! line_parameter Line number to move to - input procedure eve_line (line_parameter) local line_number, ! Local copy of line_parameter this_position, ! Marker for current cursor position last_line; ! Number of lines in buffer, including eob_text on_error message (fao ("Cannot move to line !SL", line_number)); position (this_position); return; endon_error; this_position := mark (none); if not (eve$prompt_number (line_parameter, line_number, "Line number: ", "No line number given")) then return; endif; if line_number <= 0 then message (fao ("Cannot move to line !SL", line_number)); return; endif; last_line := get_info (current_buffer, eve$kt_record_count) + 1; ! include eob_text if line_number > last_line then if last_line > 0 then message (fao ("Buffer has only !SL line!%S", last_line)); else message ("Buffer is empty"); endif; else position (beginning_of (current_buffer)); move_vertical (line_number - 1); ! already at line 1 eve$position_in_middle (mark (none)); endif; endprocedure; ! Page 59 ! Put word in all lowercase letters procedure eve_lowercase_word local word_range; ! Range for current word word_range := eve$current_word; if word_range <> 0 then change_case (word_range, lower); endif; endprocedure; ! Put word in all uppercase letters procedure eve_uppercase_word local word_range; ! Range for current word word_range := eve$current_word; if word_range <> 0 then change_case (word_range, upper); endif; endprocedure; ! Page 60 ! Set a mark for later use by go to command. ! ! Parameters: ! ! mark_parameter String to use as a mark name - input procedure eve_mark (mark_parameter) local mark_name; ! Local copy of mark_parameter, on_error message (fao ("Cannot use !AS as a mark name", mark_name)); return; endon_error; if not (eve$prompt_string (mark_parameter, mark_name, "Mark name: ", "Current position not marked")) then return; endif; eve$cleanse_string (mark_name); if length (mark_name) > eve$x_max_mark_length then mark_name := substr (mark_name, 1, eve$x_max_mark_length); endif; execute ("eve$mark_" + mark_name + " := mark (none)"); message (fao ("Current position marked as !AS", mark_name)); endprocedure; ! Page 61 ! Move to start of next/previous word, depending on current direction. ! Newlines act like words. procedure eve_move_by_word local ok; ! True if not at line boundary if current_direction = reverse then ok := eve$start_of_word; if (not ok) and (mark (none) <> beginning_of (current_buffer)) then move_horizontal (-1); endif; else ok := eve$end_of_word; if (not ok) and (mark (none) <> end_of (current_buffer)) then move_horizontal (1); endif; endif; endprocedure; ! Page 62 ! Quit Eve. If any buffers are modified, asks if you really want to ! quit. If you do quit, none of the buffers are written out before ! leaving Eve. procedure eve_quit message (eve$kt_null); set (success, off); quit; set (success, on); endprocedure; ! Page 63 ! Don't use the binding of the next key, just type the character. ! Types the entire escape sequence for a given key. Inserts or ! overstrikes depending on current mode. procedure eve_quote local quoted_char; ! 1-character string returned by read_char map (eve$prompt_window, eve$prompt_buffer); erase (eve$prompt_buffer); position (end_of (eve$prompt_buffer)); copy_text ("Press the key to be added: "); update (eve$prompt_window); quoted_char := read_char; ! don't parse the escape sequence unmap (eve$prompt_window); copy_text (quoted_char); ! rest of an escape sequence will follow endprocedure; ! Page 64 ! Search and replace procedure. Case-sensitivity of search is ! same as for the find command. If case-insensitive, replacements ! are done to match case of current occurrence. ! ! Parameters: ! ! replace_parameter_1 Old string - input ! replace_parameter_2 New string - input procedure eve_replace (replace_parameter_1, replace_parameter_2) local target, ! Local copy of replace_parameter_1 replacement, ! Local copy of replace_parameter_2 this_buffer, ! Current buffer this_mode, ! Keyword for current mode lowercase_target, ! Lowercase version of target string lowercase_replacement, ! Lowercase version of replacement string uppercase_target, ! Uppercase version of target string uppercase_replacement, ! Uppercase version of replacement string capital_target, ! Capitalized version of target string capital_replacement, ! Capitalized version of replacement string how_exact, ! Keyword to indicate case-sensitivity replace_range, ! Range of current occurrence highlight_range, ! Reverse-video version of replace_range replace_action, ! String reply to prompt action_length, ! Length of replace_action asking, ! True unless "all" option has been chosen this_occurrence, ! String of replace_range occurrences; ! Number of replacements made so far this_buffer := current_buffer; this_mode := get_info (current_buffer, eve$kt_mode); set (insert, this_buffer); asking := 1; if not (eve$prompt_string (replace_parameter_1, target, "Old string: ", "No string to replace")) then return; endif; replacement := replace_parameter_2; if replacement = eve$kt_null then replacement := read_line ("New string: "); ! empty string is ok here endif; lowercase_target := target; if get_info (lowercase_target, eve$kt_type) = string then change_case (lowercase_target, lower); endif; lowercase_replacement := replacement; change_case (lowercase_replacement, lower); if (lowercase_target = target) and (lowercase_replacement = replacement) then how_exact := no_exact; uppercase_target := target; if get_info (uppercase_target, eve$kt_type) = string then change_case (uppercase_target, upper); endif; capital_target := target; if get_info (capital_target, eve$kt_type) = string then eve$capitalize_string (capital_target); endif; uppercase_replacement := replacement; change_case (uppercase_replacement, upper); capital_replacement := replacement; eve$capitalize_string (capital_replacement); else how_exact := exact; endif; loop replace_range := eve$find (target, 1); exitif replace_range = 0; highlight_range := create_range (beginning_of (replace_range), end_of (replace_range), eve$x_highlighting); position (beginning_of (replace_range)); update (current_window); loop if asking then replace_action := read_line ("Replace? Type yes, no, all, last, or quit: "); change_case (replace_action, lower); else replace_action := "yes"; endif; action_length := length (replace_action); if (replace_action = substr ("yes", 1, action_length)) or (replace_action = substr ("all", 1, action_length)) or (replace_action = substr (eve$kt_last, 1, action_length)) or (action_length = 0) then highlight_range := 0; this_occurrence := erase_character (length (replace_range)); if how_exact = exact then copy_text (replacement); else ! Make sure non-alphabetic target is replaced by lowercase if this_occurrence = lowercase_target then copy_text (lowercase_replacement); else if this_occurrence = uppercase_target then copy_text (uppercase_replacement); else if this_occurrence = capital_target then copy_text (capital_replacement); else copy_text (lowercase_replacement); endif; endif; endif; endif; if current_direction = reverse then move_horizontal (- length (replacement)); endif; occurrences := occurrences + 1; update (current_window); if (replace_action = substr ("all", 1, action_length)) and (action_length > 0) then asking := 0; message ("Replacing all occurrences..."); set (screen_update, off); endif; exitif 1; else if (replace_action = substr ("no", 1, action_length)) or (replace_action = substr ("quit", 1, action_length)) then highlight_range := 0; if current_direction = forward then position (end_of (replace_range)); move_horizontal (1); endif; update (current_window); exitif 1; endif; endif; endloop; exitif (action_length > 0) and ((replace_action = substr ("quit", 1, action_length)) or (replace_action = substr (eve$kt_last, 1, action_length))); endloop; set (screen_update, on); message (fao ("Replaced !SL occurrence!%S", occurrences)); set (this_mode, this_buffer); endprocedure; ! Page 65 ! Restores last erased line, portion of line, or word procedure eve_restore local this_buffer, ! Marker for current cursor position this_mode, ! Keyword for current mode temp_position; ! Used to check for end of buffer this_buffer := current_buffer; this_mode := get_info (this_buffer, eve$kt_mode); temp_position := mark (none); ! check for end of buffer set (insert, this_buffer); copy_text (eve$x_restore_text); if (eve$x_restoring_line) and (temp_position <> end_of (this_buffer)) then split_line; endif; set (this_mode, this_buffer); endprocedure; ! Page 66 ! Set margins ! Set left margin without changing right margin ! ! Parameters: ! ! set_parameter New left margin - input procedure eve_set_left_margin (set_parameter) local new_left_margin, ! Local copy of set_parameter current_right_margin; ! Right margin for current buffer if not (eve$prompt_number (set_parameter, new_left_margin, "Set left margin to: ", "Left margin unchanged")) then return; endif; if new_left_margin <= 0 then message ("Left margin must be at least 1"); else current_right_margin := get_info (current_buffer, eve$kt_right_margin); if new_left_margin >= current_right_margin then message ("Left margin must be smaller than right margin " + fao ("(currently set to !SL)", current_right_margin)); else set (margins, current_buffer, new_left_margin, current_right_margin); message (fao ("Left margin set to !SL", new_left_margin)); endif; endif; endprocedure; ! Page 67 ! Set right margin without changing left margin ! ! Parameters: ! ! set_parameter New right margin - input procedure eve_set_right_margin (set_parameter) local new_right_margin, ! Local copy of set_parameter current_left_margin; ! Left margin of current buffer if not (eve$prompt_number (set_parameter, new_right_margin, "Set right margin to: ", "Right margin unchanged")) then return; endif; current_left_margin := get_info (current_buffer, eve$kt_left_margin); if new_right_margin <= current_left_margin then message ("Right margin must be greater than left margin " + fao ("(currently set to !SL) ", current_left_margin)); else if new_right_margin > eve$x_largest_right_margin then new_right_margin := eve$x_largest_right_margin; endif; set (margins, current_buffer, current_left_margin, new_right_margin); message (fao ("Right margin set to !SL", new_right_margin)); endif; endprocedure; ! Page 68 ! Go to the start of the current line. ! Display a message if already at the start of this line. procedure eve_start_of_line if get_info (current_window, eve$kt_beyond_eol) then position (search (line_begin, reverse)); else if current_offset = 0 then message ("Already at start of line"); return; else move_horizontal (- current_offset); endif; endif; ! In command buffer, don't back up beyond prompt if current_buffer = eve$command_buffer then if substr (current_line, 1, eve$x_command_prompt_length) = eve$x_command_prompt then move_horizontal (eve$x_command_prompt_length); endif; endif; endprocedure; ! Page 69 ! Used before issuing window/buffer manipulation commands. Returns true if ! current window is message window, info window, or command window, in ! which case we may not want to do the command. In these cases, the ! cursor is repositioned to either the main window or the top window, ! depending on the value of eve$x_number_of_windows. This helps people ! who accidentally get stuck in one of these windows. The calling procedure ! determines the error message or other action. In other cases, ! returns false. procedure eve$check_bad_window ! File and window commands if (current_window = message_window) or (current_window = eve$command_window) or (current_window = info_window) then if current_window = info_window then unmap (info_window); endif; position (eve$x_this_window); return (1); else return (0); endif; endprocedure; ! Page 70 ! Map a buffer to the current window. If the buffer doesn't already ! exist, create a new buffer. ! ! Parameters: ! ! buffer_parameter String containing buffer name - input procedure eve_buffer (buffer_parameter) local buffer_name, ! Local copy of buffer_parameter this_buffer, ! Current buffer loop_buffer, ! Current buffer being checked in loop loop_buffer_name, ! String containing name of loop_buffer found_a_buffer, ! True if buffer found with same exact name possible_buffer_name, ! Most recent string entered in choice buffer possible_buffer, ! Buffer whose name is possible_buffer_name how_many_buffers, ! Number of buffers listed in choice buffer new_buffer; ! New buffer created when there is no match if eve$check_bad_window then message ("Cursor has been moved to a text window; try command again"); return; endif; if not (eve$prompt_string (buffer_parameter, buffer_name, "Buffer name: ", "Buffer not switched")) then return; endif; eve$cleanse_string (buffer_name); ! See if we already have a buffer by that name this_buffer := current_buffer; loop_buffer := get_info (buffers, eve$kt_first); change_case (buffer_name, upper); ! buffer names are uppercase erase (eve$choice_buffer); loop exitif loop_buffer = 0; loop_buffer_name := get_info (loop_buffer, eve$kt_name); if buffer_name = loop_buffer_name then found_a_buffer := 1; how_many_buffers := 1; exitif 1; else if buffer_name = substr (loop_buffer_name, 1, length (buffer_name)) then eve$add_choice (loop_buffer_name); possible_buffer := loop_buffer; possible_buffer_name := loop_buffer_name; how_many_buffers := how_many_buffers + 1; endif; endif; loop_buffer := get_info (buffers, "next"); endloop; change_case (buffer_name, lower); ! for messages if found_a_buffer then if loop_buffer = this_buffer then message (fao ("Already in buffer !AS", loop_buffer_name)); else map (current_window, loop_buffer); endif; else if get_info (eve$choice_buffer, eve$kt_record_count) > 0 then if how_many_buffers = 1 then if possible_buffer = this_buffer then message (fao ("Already in buffer !AS", possible_buffer_name)); else map (current_window, possible_buffer); endif; else change_case (buffer_name, lower); eve$display_choices (fao ("Ambiguous buffer name: !AS", buffer_name)); endif; else new_buffer := create_buffer (buffer_name); eve$create_buffer_globals (new_buffer); map (current_window, new_buffer); set (eob_text, new_buffer, "[End of file]"); set (margins, new_buffer, eve$x_default_left_margin, get_info (current_window, eve$kt_width) - eve$x_default_right_margin); endif; endif; eve$set_status_line (current_window); endprocedure; ! Page 71 ! Edit a file in the current window. If the file is already in a buffer, ! use the old buffer. If not, create a new buffer. ! ! Parameters: ! ! get_file_parameter String containing file name - input procedure eve_get_file (get_file_parameter) local get_file_name, ! Local copy of get_file_parameter temp_buffer_name, ! String for buffer name based on get_file_name file_search_result, ! Latest string returned by file_search temp_file_name, ! First file name string returned by file_search loop_buffer, ! Buffer currently being checked in loop file_count, ! Number of files matching the spec temp_answer, ! Answer to "Create file?" new_buffer, ! New buffer created if needed found_a_buffer, ! True if buffer found with same name want_new_buffer; ! True if file should go into a new buffer on_error if error = tpu$_parsefail then message (fao ("Don't understand file name: !AS", get_file_name)); if eve$x_starting_up then eve$set_status_line (current_window); endif; return; endif; endon_error; if eve$check_bad_window then message ("Cursor has been moved to a text window; try command again"); return; endif; if not (eve$prompt_string (get_file_parameter, get_file_name, "File to get: ", "No file specified")) then return; endif; ! Protect against earlier file_search with same file name. file_search_result := file_search (eve$kt_null); temp_file_name := eve$kt_null; erase (eve$choice_buffer); file_count := 0; loop file_search_result := file_search (get_file_name); exitif file_search_result = eve$kt_null; file_count := file_count + 1; eve$add_choice (file_search_result); temp_file_name := file_search_result; endloop; if file_count > 1 then ! If get_file is called from eve$init_procedure, can't handle ! multiple choices, so set status line on main window and return if eve$x_starting_up then eve$set_status_line (current_window); endif; eve$display_choices (fao ("Ambiguous file name: !AS", get_file_name)); return; endif; ! Set-up to see if we already have a buffer by that name if temp_file_name = eve$kt_null then temp_buffer_name := file_parse (get_file_name, eve$kt_null, eve$kt_null, name) + file_parse (get_file_name, eve$kt_null, eve$kt_null, type); else temp_buffer_name := file_parse (temp_file_name, eve$kt_null, eve$kt_null, name) + file_parse (temp_file_name, eve$kt_null, eve$kt_null, type); endif; get_file_name := file_parse (get_file_name); ! Make sure we don't try to use a wildcard file-spec to create a new file. if file_count = 0 then if eve$is_wildcard (get_file_name) then message(fao("No files matching: !AS", get_file_name)); if eve$x_starting_up then eve$set_status_line (current_window); endif; return; endif; endif; loop_buffer := get_info (buffers, eve$kt_first); loop exitif loop_buffer = 0; if temp_buffer_name = get_info (loop_buffer, eve$kt_name) then found_a_buffer := 1; exitif 1; endif; loop_buffer := get_info (buffers, "next"); endloop; ! If there is a buffer by that name, is it the exact same file? ! If so, switch to that buffer. Otherwise use a new buffer, ! asking for a new buffer name (null new name will abort). if found_a_buffer then ! Have a buffer with the same name if temp_file_name = eve$kt_null then ! No file on disk if get_file_name = get_info (loop_buffer, eve$kt_output_file) then want_new_buffer := 0; else want_new_buffer := 1; endif; else ! Check to see if the same file if (temp_file_name = get_info (loop_buffer, eve$kt_output_file)) or (temp_file_name = get_info (loop_buffer, eve$kt_file_name)) then want_new_buffer := 0; else want_new_buffer := 1; endif; endif; if want_new_buffer then message (fao ("Buffer name !AS is in use", temp_buffer_name)); temp_buffer_name := read_line ("Type a new buffer name or press Return to cancel: "); if temp_buffer_name = eve$kt_null then message ("No new buffer created"); else new_buffer := eve$create_buffer (temp_buffer_name, get_file_name, temp_file_name); endif; else if current_buffer = loop_buffer then message (fao ("Already editing file !AS", get_file_name)); else map (current_window, loop_buffer); endif; endif; else ! No buffer with the same name, so create a new buffer new_buffer := eve$create_buffer (temp_buffer_name, get_file_name, temp_file_name); endif; if new_buffer <> 0 then set (eob_text, new_buffer, "[End of file]"); set (margins, new_buffer, eve$x_default_left_margin, get_info (current_window, eve$kt_width) - eve$x_default_right_margin); endif; ! Correct the status line in any event eve$set_status_line (current_window); endprocedure; procedure eve$is_wildcard (the_string) if index (the_string, "*") <> 0 then return (TRUE); endif; if index (the_string, "%") <> 0 then return (TRUE); endif; if index (the_string, "...") <> 0 then return (TRUE); endif; return (FALSE); endprocedure ! Page 72 ! Procedure called by eve_get_file to create a new buffer and map it ! to the current window. Returns the created buffer, or zero if error. ! ! Parameters: ! ! buffer_name Name of new buffer - input ! requested_file_name Full VMS filespec to use - input ! actual_file_name From file_search; "" if not on disk - input procedure eve$create_buffer (buffer_name, requested_file_name, actual_file_name) local new_buffer; ! Buffer created on_error if error = tpu$_dupbufname then message (fao ("Buffer !AS already exists", substr (buffer_name, 1, eve$x_max_buffer_name_length))); return (0); endif; endon_error; if actual_file_name = eve$kt_null then if eve$x_starting_up and (get_info (command_line, "create") = 0) then message (fao ("Input file does not exist: !AS", requested_file_name)); exit; endif; new_buffer := create_buffer (buffer_name); message (fao ("Editing new file; could not find !AS", requested_file_name)); !!!!!!!! message ("Editing new file"); set (output_file, new_buffer, requested_file_name); else new_buffer := create_buffer (buffer_name, actual_file_name); set (output_file, new_buffer, actual_file_name); endif; map (current_window, new_buffer); if eve$x_starting_up and get_info (command_line, "read_only") then set (no_write, new_buffer); endif; ! Call dummy procedure to handle buffer specific stuff eve$create_buffer_globals(new_buffer); return (new_buffer); endprocedure; ! Page 73 ! Like read_file built-in, but positions the cursor at the start of ! the inserted file. Handles wildcarding in file name. ! ! Parameters: ! ! include_file_parameter String containing file name - input procedure eve_include_file (include_file_parameter) local include_file_name, ! Local copy of include_file_parameter started_at_bof, ! True if current position at start of file include_position, ! Marker for where cursor should end up temp_file_name, ! First file name string - from file_parse file_search_result; ! Latest string returned by file_search on_error if error = tpu$_parsefail then message (fao ("Don't understand file name: !AS", include_file_name)); return; endif; endon_error; if eve$check_bad_window then message ("Cursor has been moved to a text window; try command again"); return; endif; if not (eve$prompt_string (include_file_parameter, include_file_name, "File to include: ", "No file included")) then return; endif; if mark (none) = beginning_of (current_buffer) then started_at_bof := 1; else started_at_bof := 0; endif; if started_at_bof then include_position := mark (none); else move_horizontal (-1); include_position := mark (none); move_horizontal (1); endif; ! Initialize to null string and protect against earlier file_search ! with same file name. temp_file_name := file_search (eve$kt_null); temp_file_name := file_parse (include_file_name); erase (eve$choice_buffer); loop file_search_result := file_search (include_file_name); exitif file_search_result = eve$kt_null; eve$add_choice (file_search_result); temp_file_name := file_search_result; endloop; case get_info (eve$choice_buffer, eve$kt_record_count) from 0 to 1 [0] : message (fao ("Could not include file: !AS", include_file_name)); [1] : read_file (temp_file_name); if started_at_bof then position (beginning_of (current_buffer)); else position (include_position); move_horizontal (1); endif; [outrange] : eve$display_choices (fao ("Ambiguous file name: !AS", include_file_name)); endcase; endprocedure; ! Page 74 ! Go from two windows to one window. Do nothing if only one window on screen. procedure eve_one_window local this_position, ! Marker for current cursor position this_buffer; ! Current buffer eve$check_bad_window; this_position := mark (none); ! ensure VAXTPU knows current position this_buffer := current_buffer; if eve$x_number_of_windows = 1 then message ("Only one window on screen"); else unmap (eve$top_window); unmap (eve$bottom_window); map (message_window, message_buffer); map (eve$main_window, this_buffer); eve$set_status_line (eve$main_window); position (this_position); eve$x_number_of_windows := 1; eve$x_this_window := eve$main_window; endif; endprocedure; ! Page 75 ! Switch to other window procedure eve_other_window eve$check_bad_window; if eve$x_number_of_windows = 1 then message ("Only one window on screen"); else if current_window = eve$top_window then position (eve$bottom_window); else position (eve$top_window); endif; eve$x_this_window := current_window; endif; endprocedure; ! Page 76 ! Split current window into two windows, both pointing to the same buffer. ! Move to lower window. Don't do anything if there are already 2 windows. procedure eve_two_windows local this_position, ! Marker for current cursor position this_buffer; ! Current buffer eve$check_bad_window; this_position := mark (none); ! ensure VAXTPU knows current position this_buffer := current_buffer; if eve$x_number_of_windows = 2 then message ("Already two windows on screen"); else unmap (eve$main_window); map (message_window, message_buffer); map (eve$top_window, this_buffer); eve$set_status_line (eve$top_window); update (eve$top_window); map (eve$bottom_window, this_buffer); eve$set_status_line (eve$bottom_window); update (eve$bottom_window); eve$x_number_of_windows := 2; eve$x_this_window := eve$bottom_window; endif; endprocedure; ! Page 77 ! Write the current buffer to a specified file. If no file specified, ! use the default file name. ! ! Parameters: ! ! write_file_name ! String containing file name - input procedure eve_write_file (write_file_name) local write_result; ! File name string returned by write_file if eve$x_trimming then message ("Trimming buffer..."); eve$trim_buffer (current_buffer); message ("Trimming completed"); endif; if write_file_name = eve$kt_null then write_result := write_file (current_buffer); else write_result := write_file (current_buffer, write_file_name); endif; set (output_file, current_buffer, write_result); endprocedure; ! Page 78 ! Refresh screen and clear message window procedure eve_refresh ! Additional screen commands message (eve$kt_null); ! clear message window without deleting messages refresh; endprocedure; ! Page 79 ! Set tabs at specified positions ! ! Parameters: ! ! set_parameter String that contains tab settings - input procedure eve_set_tabs_at (set_parameter) local tab_settings; ! Local copy of set_parameter on_error message ("Could not change tab stops as specified"); return; endon_error; if eve$prompt_string (set_parameter, tab_settings, "Set tabs at: ", "Tab settings not changed") then set (tab_stops, current_buffer, tab_settings); message ("Tab stops set"); endif; endprocedure; ! Page 80 ! Set tabs at constant increments - every n columns ! ! Parameters: ! ! set_parameter Integer increment for tab stops - input procedure eve_set_tabs_every (set_parameter) local tab_increment; ! Local copy of set_parameter on_error message ("Could not change tab stops as specified"); return; endon_error; if eve$prompt_number (set_parameter, tab_increment, "Set tabs every: ", "Tab settings not changed") then if tab_increment <= 0 then message ("Tabs must be set at least 1 space apart"); else set (tab_stops, current_buffer, tab_increment); message ("Tab stops set"); endif; endif; endprocedure; ! Page 81 ! Set width for all windows ! ! Parameters: ! ! set_parameter ! Number of columns per line - input procedure eve_set_width (set_parameter) local new_width, ! Local copy of set parameter loop_window, ! Window currently being checked in loop last_window; ! Last VAXTPU window if not (eve$prompt_number (set_parameter, new_width, "Set width to: ", "Width not changed")) then return; endif; if new_width <= 0 then message (fao ("Cannot set width to !SL", new_width)); return; else if new_width > eve$x_largest_width then new_width := eve$x_largest_width; endif; endif; last_window := get_info (windows, eve$kt_last); loop_window := get_info (windows, eve$kt_first); loop set (width, loop_window, new_width); exitif loop_window = last_window; loop_window := get_info (windows, "next"); endloop; message (fao ("Width set to !SL", new_width)); endprocedure; ! Page 82 ! Shift procedures (horizontal scrolling) ! Shift left to reverse effects of shift right. ! ! Parameters: ! ! shift_parameter Number of columns to shift left - input procedure eve_shift_left (shift_parameter) local shift_amount; ! Local copy of shift_parameter if eve$prompt_number (shift_parameter, shift_amount, "Number of columns to shift left: ", "No columns shifted") then if shift_amount < 0 then message ("Cannot shift left by a negative amount"); else message (fao ("Window is now shifted right !SL column!%S", shift (current_window, - shift_amount))); endif; endif; endprocedure; ! Shift right to see rest of line beyond right-hand screen boundary. ! ! Parameters: ! ! shift_parameter Number of columns to shift right - input procedure eve_shift_right (shift_parameter) local shift_amount; ! Local copy of shift_parameter if eve$prompt_number (shift_parameter, shift_amount, "Number of columns to shift right: ", "No columns shifted") then if shift_amount < 0 then message ("Cannot shift right by a negative amount"); else message (fao ("Window is now shifted right !SL column!%S", shift (current_window, shift_amount))); endif; endif; endprocedure; ! Page 83 ! Show information about all non-system buffers, one at a time. ! Ask if user wants more information after each buffer. procedure eve_show local this_position, ! Marker for current cursor position this_window, ! Current window this_buffer, ! Current buffer buffer_to_show, ! Buffer passed to eve$show_buffer_info window_to_show, ! Window passed to eve$show_buffer_info next_buffer, ! Next candidate buffer show_key, ! String associated with key read after prompt throw_away; ! Result of eve$prompt_key - to resume editing this_position := mark (none); this_buffer := current_buffer; this_window := current_window; buffer_to_show := current_buffer; window_to_show := current_window; next_buffer := get_info (buffers, eve$kt_last); map (info_window, show_buffer); set (status_line, info_window, reverse, " Show buffer (" + eve$kt_version + ")"); loop exitif next_buffer = 0; if (next_buffer <> this_buffer) and (get_info (next_buffer, "system") = 0) then erase (show_buffer); eve$show_buffer_info (buffer_to_show, window_to_show); if buffer_to_show = this_buffer then window_to_show := 0; endif; update (info_window); show_key := eve$lookup_comment (eve$prompt_key ("Press Do for more information, Return to resume editing: ")); if show_key = "do" then buffer_to_show := next_buffer; else unmap (info_window); position (this_window); return; endif; endif; next_buffer := get_info (buffers, "previous"); endloop; erase (show_buffer); eve$show_buffer_info (buffer_to_show, window_to_show); update (info_window); throw_away := eve$prompt_key ("Press any key to resume editing: "); unmap (info_window); position (this_window); endprocedure; ! Page 84 ! Main routine called by show command. Append information about the given ! buffer to the end of the show_buffer. Mapping, erasing, etc. are ! handled in eve_show. ! ! Parameters: ! ! this_buffer Buffer being inquired about - input ! this_window Window being inquired about - input procedure eve$show_buffer_info (this_buffer, this_window) local input_file_name, ! String with input file name for this_buffer output_file_name, ! String with output file name for this_buffer how_many_records, ! Number of records in this_buffer record_text, ! String for display of how_many_records this_window_shift, ! Shift amount for this_window this_window_key_map, ! The key-map list for this window what_tab_stops; ! String or integer with tab stop settings on_error ! Trap messages with tpu$_nonames and tpu$_multiplenames endon_error; position (end_of (show_buffer)); set (insert, show_buffer); ! should be insert anyway, but just in case... copy_text (fao (" Information about buffer !AS", get_info (this_buffer, eve$kt_name))); eve$letter_wrap (27); split_line; split_line; copy_text (" Input file: "); input_file_name := get_info (this_buffer, eve$kt_file_name); if input_file_name = eve$kt_null then copy_text ("none"); else copy_text (input_file_name); eve$letter_wrap (15); endif; split_line; copy_text (" Output file: "); output_file_name := get_info (this_buffer, eve$kt_output_file); if (output_file_name = 0) or (get_info (this_buffer, "no_write")) then copy_text ("none"); else copy_text (output_file_name); eve$letter_wrap (15); endif; split_line; split_line; if get_info (this_buffer, "modified") then copy_text (" Modified ") else copy_text (" Not modified "); endif; copy_text (fao ("Left margin set to !SL", get_info (this_buffer, eve$kt_left_margin))); split_line; if get_info (current_buffer, eve$kt_mode) = insert then copy_text (" Insert mode "); else copy_text (" Overstrike mode "); endif; copy_text (fao ("Right margin set to !SL", get_info (this_buffer, eve$kt_right_margin))); split_line; if get_info (this_buffer, "direction") = forward then copy_text (" Forward direction "); else copy_text (" Reverse direction "); endif; if this_window <> 0 then copy_text (fao ("Window width set to !SL", get_info (this_window, eve$kt_width))); endif; split_line; how_many_records := get_info (this_buffer, eve$kt_record_count); if how_many_records > 0 then record_text := fao (" !SL line!%S", how_many_records); else record_text := " No lines"; endif; copy_text (record_text); if length (record_text) >= 32 then copy_text (" "); else copy_text (substr (eve$kt_spaces, 1, 32 - length (record_text))); endif; if this_window <> 0 then this_window_shift := get_info (this_window, "shift_amount"); if this_window_shift > 0 then copy_text (fao ("Window shifted right by !SL columns", this_window_shift)); endif; endif; split_line; split_line; what_tab_stops := get_info (this_buffer, "tab_stops"); if get_info (what_tab_stops, eve$kt_type) = integer then copy_text (fao (" Tab stops set every !SL columns", what_tab_stops)); else copy_text (fao (" Tab stops set at columns !AS", what_tab_stops)); eve$letter_wrap (27); endif; split_line; this_window_key_map := get_info(this_buffer, "key_map_list"); if this_window_key_map <> eve$x_key_map_list then split_line; if this_window_key_map <> '' then copy_text(fao(" Key map list: !AS", this_window_key_map)); else copy_text(" No key map list"); endif; split_line; endif; ! Move to choice buffer to work with mark names eve$expand_to_choices (expand_name ("eve$mark_", variables)); loop exitif mark (none) = end_of (eve$choice_buffer); execute ("eve$x_buffer_of_mark:=get_info(" + current_line + ",eve$kt_buffer)"); if eve$x_buffer_of_mark = this_buffer then erase_character (9); move_vertical (1); else erase_line; endif; endloop; if get_info (eve$choice_buffer, eve$kt_record_count) = 0 then position (end_of (show_buffer)); copy_text (" No marks"); else eve$format_choices; position (end_of (show_buffer)); copy_text (" Marks: "); split_line; split_line; copy_text (eve$choice_buffer); endif; if current_offset > 0 then split_line; endif; endprocedure; ! Page 85 ! Attach back to the parent process. Used when Eve is spawned from DCL ! and run in a subprocess ("kept Eve"). The VAXTPU attach command can ! be used for more flexible process control. procedure eve_attach ! Advanced commands on_error if error = tpu$_noparent then message ("You are not running EVE in a subprocess"); return; endif; endon_error; message (eve$kt_null); ! Clear out old message attach; endprocedure; ! Page 86 ! Run a DCL command and put the output in a second window on the screen. ! This is the only command to automatically create a second window if ! needed, but the user is left in the current buffer at the end of the ! command (reduce trap-door risk). Returns true if successful, false ! if no dcl command was issued. ! ! Parameters: ! ! dcl_parameter String containing DCL command - input procedure eve_dcl (dcl_parameter) local dcl_string, ! Local copy of dcl_parameter this_position, ! Marker for current cursor position this_buffer; ! Current buffer on_error if error = tpu$_createfail then message ("DCL subprocess could not be created"); return (0); endif; endon_error; if not (eve$prompt_string (dcl_parameter, dcl_string, "DCL command: ", "No DCL command given")) then return; endif; if (get_info (eve$x_dcl_process, eve$kt_type) = unspecified) or (eve$x_dcl_process = 0) then message ("Creating DCL subprocess..."); eve$x_dcl_process := create_process (eve$dcl_buffer, "$ set noon"); endif; this_buffer := current_buffer; this_position := mark (none); if this_buffer <> eve$dcl_buffer then if eve$x_number_of_windows = 2 then eve_other_window; if current_buffer <> eve$dcl_buffer then map (current_window, eve$dcl_buffer); endif; else unmap (eve$main_window); map (eve$top_window, this_buffer); eve$set_status_line (eve$top_window); update (eve$top_window); map (eve$bottom_window, eve$dcl_buffer); eve$x_number_of_windows := 2; eve$x_this_window := eve$bottom_window; endif; endif; set (status_line, current_window, reverse, " DCL buffer"); position (end_of (eve$dcl_buffer)); ! Process the DCL string - need to include the $ split_line; copy_text (dcl_string); update (current_window); send (dcl_string, eve$x_dcl_process); position (end_of (eve$dcl_buffer)); update (current_window); if this_buffer <> eve$dcl_buffer then eve_other_window; endif; return (1); endprocedure; ! Page 87 ! Associate a key with an Eve command. Prompts for the key. ! Defined keys can be indentified by a leading space in the comment field. ! Need this to be able to differentiate during keypad initialization. ! ! Parameters: ! ! define_parameter String containing command name - input procedure eve_define_key (define_parameter) local command_name, ! Local copy of define_parameter full_command_name, ! Full command string returned by eve$parse the_key, ! Keyword for key to be defined paren_index, ! Index into full_command_name to end name define_comment; ! String (with leading space) to associate ! with the_key on_error if error = tpu$_notdefinable then message ("No key defined"); return; endif; endon_error; if not (eve$prompt_string (define_parameter, command_name, eve$x_eve_command_prompt, "No key defined")) then return; endif; full_command_name := eve$parse (command_name); ! Eve$Parse will display messages and handle ambiguities if full_command_name = eve$kt_null then return; endif; the_key := eve$prompt_key ("Press the key that you want to define: "); paren_index := index (full_command_name, "("); if paren_index = 0 then define_comment := substr (full_command_name, 5, length (full_command_name)); else define_comment := substr (full_command_name, 5, paren_index - 5); endif; ! Return gets you out without redefining a key if the_key = ret_key then message ("No key defined"); else if eve$lookup_comment (the_key) = "do" then message ("You cannot bind another command to the DO key"); else if eve$alphabetic (the_key) = eve$kt_null then define_key (full_command_name, the_key, define_comment, eve$x_user_keys); message ("Key defined"); else message ("You cannot bind another command to a typing key"); endif; endif; endif; endprocedure; ! Page 88 ! Compile the procedure in the current buffer. If name = "*", compile ! the entire buffer. Otherwise, compile procedure with this name. ! Procedure and endprocedure statements must start in column 1. ! ! Parameters: ! ! extend_parameter String containing procedure name or * - input procedure eve_extend_tpu (extend_parameter) local procedure_name, ! Local copy of extend_parameter this_position, ! Marker for current cursor position this_informational, ! Keyword for display of informational messages search_pattern, ! Pattern used to search for start of procedure search_range, ! Temporary range for start of/end of procedure start_procedure, ! Marker at beginning of "procedure" partial_range, ! Range including "procedure" and whitespace procedure_range, ! Range including procedure name identifier this_name, ! Procedure name string from procedure_range whole_procedure_range, ! Range including entire procedure definition found_a_procedure; ! True if procedure is found on_error if error = tpu$_compilefail then ! VAXTPU will produce message message ("Error in compiling; TPU not extended"); position (this_position); set (informational, this_informational); return; endif; if error = tpu$_strnotfound then search_range := 0; endif; endon_error; if not (eve$prompt_string (extend_parameter, procedure_name, "Procedure name: ", "TPU not extended")) then return; endif; eve$cleanse_string (procedure_name); this_position := mark (none); if get_info (system, "informational") then this_informational := on; else this_informational := off; endif; if procedure_name = "*" then message ("Extending TPU..."); set (informational, on); compile (current_buffer); set (informational, this_informational); message ("TPU extended"); return; endif; erase (eve$choice_buffer); message (fao ("Searching for procedure !AS...", procedure_name)); position (end_of (current_buffer)); search_pattern := line_begin & "procedure" & span (eve$x_word_separators) @ partial_range & procedure_name; loop search_range := search (search_pattern, reverse); exitif search_range = 0; position (beginning_of (search_range)); ! Get entire name of this procedure start_procedure := mark (none); position (end_of (partial_range)); move_horizontal (1); procedure_range := search (eve$pattern_procname, forward); ! Find corresponding endprocedure search_range := search (eve$pattern_endprocedure, forward); if search_range = 0 then found_a_procedure := 0; else position (end_of (search_range)); whole_procedure_range := create_range (start_procedure, mark (none), none); found_a_procedure := 1; endif; ! If we have a whole procedure, check for exact match etc. if found_a_procedure then this_name := substr (procedure_range, 1, length (procedure_range)); if this_name = procedure_name then erase (eve$choice_buffer); eve$add_choice (this_name); exitif 1; else eve$add_choice (this_name); endif; endif; position (start_procedure); exitif mark (none) = beginning_of (current_buffer); move_horizontal (-1); endloop; case get_info (eve$choice_buffer, eve$kt_record_count) from 0 to 1 [0] : message (fao ("Could not find procedure: !AS", procedure_name)); [1] : message ("Extending TPU..."); set (informational, on); compile (whole_procedure_range); set (informational, this_informational); message ("TPU extended"); [outrange] : eve$display_choices (fao ("Ambiguous procedure name: !AS", procedure_name)); endcase; position (this_position); endprocedure; ! Page 89 ! Learn mode procedures ! Begin learn sequence procedure eve_learn message ("Press keystrokes to be learned. Press CTRL/R to remember these keystrokes."); learn_begin (exact); endprocedure; ! Remember a learn sequence. Must be bound to a key in order to work; ! cannot be used from command line procedure eve_remember local learn_sequence, ! Learn sequence returned by end_learn builtin learn_key, ! Keyword for key to bind sequence to define_error; ! Integer - true if recursive key definition on_error if error = tpu$_notlearning then message ("Nothing to remember"); return; else if error = tpu$_recurlearn then define_error := 1; endif; endif; endon_error; learn_sequence := learn_end; loop learn_key := eve$prompt_key ("Press the key that you want to use to do what was just learned: "); ! Return gets you out without redefining a key if learn_key = ret_key then message ("Key sequence not remembered"); return; endif; if eve$lookup_comment (learn_key) = "do" then message ("You cannot use the DO key for a learn sequence"); else if eve$alphabetic (learn_key) = eve$kt_null then define_key (learn_sequence, learn_key, "sequence", eve$x_user_keys); if define_error then message ("That key was already used in the learn sequence"); define_error := 0; else ! clear LEARN message if still there message ("Key sequence remembered"); exitif 1; endif; else message ("You cannot use a typing key for a learn sequence"); endif; endif; endloop; endprocedure; ! Page 90 ! Repeat next command n times ! ! Parameters: ! ! repeat_parameter Number of times to repeat next command - input procedure eve_repeat (repeat_parameter) local count, ! Local copy of repeat_parameter next_key, ! Keyword of next key following repeat command ascii_next_key, ! String of next_key key_program, ! Program associated with next_key repeat_key; ! String associated with next_key if not (eve$prompt_number (repeat_parameter, count, "Number of times to repeat: ", "Will not repeat next command")) then return; endif; if count <= 1 then message ("Will not repeat next command"); else message (fao ("Will repeat next command !SL times", count)); update (message_window); next_key := read_key; if eve$lookup_comment (next_key) = "shift key" then next_key := eve$get_shift_key; endif; message (eve$kt_null); ascii_next_key := eve$alphabetic (next_key); if ascii_next_key <> eve$kt_null then loop exitif count = 0; copy_text (ascii_next_key); count := count - 1; endloop; else ! Check for do key repeat_key := eve$lookup_comment (next_key); if repeat_key = "do" then eve$x_repeat_count := count; eve$enter_command_window; else key_program := lookup_key (next_key, program); if key_program <> 0 then loop exitif count = 0; execute (key_program); count := count - 1; endloop; else message ("Cannot repeat that key"); endif; endif; endif; update (current_window); endif; endprocedure; ! Page 91 ! Save the current environment using the VAXTPU save command ! ! Parameters: ! ! save_parameter String containing name of section file - input procedure eve_save_extended_tpu (save_parameter) local save_file; ! Local copy of save_parameter if eve$prompt_string (save_parameter, save_file, "File to save in: ", "Status not saved") then save (save_file); endif; endprocedure; ! Page 92 ! Allow users to define a shift key (like EDT gold key) ! Eve command to let the user set the shift key. ! If changing the shift key, must do a TPU UNDEFINE_KEY () of ! the current shift key before using this command. Otherwise, ! the user will wind up with multiple shift keys. procedure eve_set_shift_key local the_key; ! Keyword for key to be used as shift key the_key := eve$prompt_key ("Press the key that you want to use as the shift key: "); if the_key = ret_key then message ("No shift key set"); else if eve$lookup_comment (the_key) = "do" then message ("You cannot make the DO key the shift key"); else if eve$alphabetic (the_key) = eve$kt_null then set (shift_key, the_key); define_key ("execute (lookup_key (eve$get_shift_key, program))", the_key, "shift key", eve$x_user_keys); message ("Shift key set"); else message ("You cannot make a typing key the shift key"); endif; endif; endif; endprocedure; ! VAXTPU does not save the shift key across sessions, so we have to ! be tricky to make it work. When Eve's set shift key command is used, ! it sets the shift key, but also does a define_key to this procedure. ! The define_key, unlike the shift setting, is saved across sessions. ! This procedure sets the shift key to the last (i.e. current) key, ! reads in the next key, and returns the shifted key. procedure eve$get_shift_key local key_to_shift; ! Keyword for key pressed after shift key set (shift_key, last_key); key_to_shift := key_name (read_key, shift_key); return (key_to_shift); endprocedure; ! Page 93 ! Spawn a new DCL subprocess and go to that subprocess. Logging out of ! the subprocess will resume the Eve session. Useful for running ! screen-oriented programs that can't go through VMS mailboxes. procedure eve_spawn on_error if error = tpu$_createfail then message ("DCL subprocess could not be created"); return; endif; endon_error; message (eve$kt_null); ! Clear out old message spawn; endprocedure; ! Page 94 ! Execute a VAXTPU command line ! ! Parameters: ! ! tpu_parameter VAXTPU command string - input procedure eve_tpu (tpu_parameter) local tpu_command, ! Local copy of tpu_parameter this_informational; ! Keyword for display of informational messages if eve$prompt_string (tpu_parameter, tpu_command, "TPU command: ", "No TPU command given") then if get_info (system, "informational") then this_informational := on; else this_informational := off; endif; set (informational, on); execute (tpu_command); set (informational, this_informational); if current_window = info_window then set (status_line, info_window, reverse, " " + get_info (current_buffer, eve$kt_name) + " buffer"); endif; endif; endprocedure; ! Page 95 ! Procedures to support command-line editor ! Set up command line editor procedure eve$enter_command_window ! Command line parser local this_position; ! Marker for current cursor position if not eve$x_starting_up then eve$x_start_do_key := eve$lookup_comment (last_key); endif; if current_window = info_window then unmap (info_window); position (eve$x_this_window); endif; this_position := mark (none); eve$x_pre_command_window := current_window; position (eve$command_window); position (end_of (eve$command_buffer)); copy_text (eve$x_command_prompt); endprocedure; ! Leave command line editor. ! Does not leave if there is an ambiguity, with choices in the ! choice window. procedure eve$exit_command_window local current_command_line, ! String containing current command buffer line temp_position; ! Marker for cursor position in command buffer if current_window <> eve$command_window then message ("Not in command window"); else if not eve$x_starting_up then eve$x_stop_do_key := eve$lookup_comment (last_key); endif; ! Test for end of buffer to avoid move_vertical errors temp_position := mark (none); if temp_position <> end_of (eve$command_buffer) then current_command_line := current_line; move_horizontal (- current_offset); move_vertical (1); temp_position := mark (none); if temp_position <> end_of (eve$command_buffer) then position (end_of (eve$command_buffer)); move_vertical (-1); erase_line; copy_text (current_command_line); endif; else current_command_line := eve$kt_null; endif; if substr (current_command_line, 1, eve$x_command_prompt_length) = eve$x_command_prompt then current_command_line := substr (current_command_line, eve$x_command_prompt_length + 1, length (current_command_line)); endif; position (eve$x_pre_command_window); message (eve$kt_null); ! clear out message window without deleting messages eve$x_command_line_flag := TRUE; eve$parser_dispatch(current_command_line); eve$x_command_line_flag := FALSE; endif; endprocedure; ! Page 96 ! Process command selected in command line editor ! ! Parameters: ! ! new_do_line String containing Eve command - input procedure eve$process_command (new_do_line) local repetitions, ! Number of times to execute this command this_position, ! Marker for current cursor position this_window; ! Current window ! Make sure we do not repeat the current repeat command repetitions := eve$x_repeat_count; eve$x_repeat_count := 1; if new_do_line <> eve$kt_null then eve$x_do_line := new_do_line; eve$x_parsed_do_line := eve$parse (eve$x_do_line); if eve$x_parsed_do_line = eve$kt_null then ! message sent during parse error eve$x_do_line := eve$kt_null; else ! Unmap choice window before executing the command if get_info (eve$choice_window, eve$kt_buffer) <> 0 then unmap (eve$choice_window); endif; loop exitif repetitions = 0; execute (eve$x_parsed_do_line); repetitions := repetitions - 1; endloop; endif; else eve$x_ambiguous_parse := 0; ! need this since eve$parse is not called here if (eve$x_start_do_key = "do") and (eve$x_stop_do_key = "do") then if eve$x_do_line = eve$kt_null then message ("No previous command given"); else message (fao ("Doing previous command: !AS", eve$x_do_line)); loop exitif repetitions = 0; execute (eve$x_parsed_do_line); repetitions := repetitions - 1; endloop; endif; else message ("No command given"); endif; endif; if eve$x_ambiguous_parse then if get_info (eve$choice_window, eve$kt_buffer) = 0 then map (eve$choice_window, eve$choice_buffer); endif; if get_info (eve$choice_buffer, eve$kt_record_count) >= eve$x_choice_window_length then set (status_line, eve$choice_window, reverse, " Choices Press Next Screen or Prev Screen to see other choices"); else set (status_line, eve$choice_window, reverse, " Choices"); endif; update (eve$choice_window); position (eve$command_window); position (end_of (eve$command_buffer)); move_horizontal (-1); else ! Unmap choice window if not done previously if get_info (eve$choice_window, eve$kt_buffer) <> 0 then unmap (eve$choice_window); endif; this_position := mark (none); this_window := current_window; position (eve$command_window); position (end_of (eve$command_buffer)); if new_do_line = eve$kt_null then move_vertical (-1); erase_line; endif; update (eve$command_window); position (this_window); position (this_position); endif; endprocedure; ! Page 97 ! VMS V4-style recall command procedure eve_recall local recall_line; ! String containing command line to be recalled on_error message ("No more commands to recall"); move_vertical (1); move_horizontal (-1); return; endon_error; if current_buffer <> eve$command_buffer then eve$enter_command_window; endif; move_horizontal (- (current_offset + 1)); endprocedure; ! Page 98 ! Command line interpreter ! ! Parameters: ! ! do_parameter String containing Eve command - input procedure eve_do (do_parameter) local do_line; ! Local copy of do_parameter do_line := do_parameter; if (length (do_line) > 0) then eve$process_command (do_line); else if current_window = eve$command_window then eve$exit_command_window; else eve$enter_command_window; endif; endif; endprocedure; ! Page 99 ! Procedures to do command line parsing ! These procedures use the following global variables: ! ! eve$x_command_line Result of read_line ! eve$x_command_index Index into eve$x_command_line while parsing ! eve$x_command_length Length of eve$x_command_line ! eve$x_is_symbol | ! eve$x_is_quoted_string | Used to indicate token type ! eve$x_is_punctuation | ! eve$x_is_number | ! ! Move eve$x_command_index over whitespace. Stay put if not on whitespace ! when starting. procedure eve$index_over_whitespace local c; ! Current character in command line loop exitif eve$x_command_index > eve$x_command_length; c := substr (eve$x_command_line, eve$x_command_index, 1); exitif index (eve$x_token_separators, c) = 0; eve$x_command_index := eve$x_command_index + 1; endloop; endprocedure; ! Page 100 ! Eve$get_token returns the next token in the command line. ! Returns a null string if no more tokens. ! ! Tokens include symbols, quoted strings, and punctuation, and strings ! that are "none of the above." A quoted string at the end of a line ! does not have to have a final close quote. procedure eve$get_token local original_index, ! Original index into command line quote_char, ! Quote character being used for quoted string c, ! Current character in command line closed_quote, ! True if quote_char ends quoted string work_token; ! Temporary string for building current token quote_char := eve$kt_null; c := eve$kt_null; closed_quote := 0; work_token := eve$kt_null; eve$x_is_symbol := 0; eve$x_is_quoted_string := 0; eve$x_is_punctuation := 0; eve$x_is_number := 1; eve$index_over_whitespace; original_index := eve$x_command_index; if eve$x_command_index > eve$x_command_length then eve$x_is_number := 0; eve$get_token := eve$kt_null; return; endif; c := substr (eve$x_command_line, eve$x_command_index, 1); if index (eve$x_symbol_characters, c) > 0 then eve$x_is_symbol := 1; loop eve$x_is_number := eve$x_is_number and (index (eve$x_digit_characters, c) > 0); eve$x_is_symbol := eve$x_is_symbol and (index (eve$x_symbol_characters, c) > 0); eve$x_command_index := eve$x_command_index + 1; exitif eve$x_command_index > eve$x_command_length; c := substr (eve$x_command_line, eve$x_command_index, 1); exitif index (eve$x_token_separators, c) > 0; endloop; eve$get_token := substr (eve$x_command_line, original_index, eve$x_command_index - original_index); return; endif; eve$x_is_number := 0; if (c = "'") or (c = '"') then eve$x_is_quoted_string := 1; quote_char := c; loop eve$x_command_index := eve$x_command_index + 1; exitif eve$x_command_index > eve$x_command_length; c := substr (eve$x_command_line, eve$x_command_index, 1); if c = quote_char then ! Check for doubled quotes eve$x_command_index := eve$x_command_index + 1; if eve$x_command_index > eve$x_command_length then closed_quote := 1; exitif 1; endif; c := substr (eve$x_command_line, eve$x_command_index, 1); if c <> quote_char then closed_quote := 1; exitif 1; endif; endif; endloop; work_token := substr (eve$x_command_line, original_index, eve$x_command_index - original_index); ! Add close quote if there wasn't one due to end of line. if closed_quote then eve$get_token := work_token; else eve$get_token := work_token + quote_char; endif; return; endif; ! Not a symbol, not a quoted string, so just return the single character and ! set eve$x_punctuation. eve$x_punctuation := 1; eve$x_command_index := eve$x_command_index + 1; eve$get_token := substr (eve$x_command_line, original_index, 1); endprocedure; ! Page 101 ! Procedure which helps in recognizing multi-word commands. ! If initial_token is an initial substring of full_token, ! return the largest substring of full_token which contains no ! more underscores than initial_token. Otherwise return the null string. ! ! Parameters: ! ! initial_token Prefix string - input ! full_token Entire string - input procedure eve$complete (initial_token, full_token) local underscore_index; ! Index of next underscore in full_token ! that is not found in initial_token if initial_token <> substr (full_token, 1, length (initial_token)) then return (eve$kt_null); endif; if initial_token = full_token then return (initial_token); endif; underscore_index := index (substr (full_token, length (initial_token) + 1, length (full_token)), "_"); if underscore_index = 0 then eve$complete := full_token; else eve$complete := substr (full_token, 1, length (initial_token) + underscore_index - 1); endif; return; endprocedure; ! Page 102 ! Procedure for handling quoted string. Takes the argument, doubles ! all quotation marks, and return the resulting string. ! ! Parameters: ! ! string_with_quotes String being processed - input procedure eve$double_quotes (string_with_quotes) local result_string, ! Portion of string with quotes doubled rest_of_string, ! Remainder of string yet to be processed quote_index; ! Index of double-quote in rest_of_string result_string := eve$kt_null; rest_of_string := string_with_quotes; loop quote_index := index (rest_of_string, '"'); if quote_index = 0 then result_string := result_string + rest_of_string; exitif 1; else result_string := result_string + substr (rest_of_string, 1, quote_index) + '"'; exitif quote_index = length (rest_of_string); rest_of_string := substr (rest_of_string, quote_index + 1, length (rest_of_string)); endif; endloop; return (result_string); endprocedure; ! Page 103 ! Procedure for handling the last string argument in a command line ! when it is not a quoted string. Returns result of parse after ! handling the string. ! ! Parameters: ! ! result_so_far String containing parse to date - input ! current_token String containing current token - input procedure eve$add_final_string (result_so_far, current_token) local parse_result, ! Result of parsing complete command line rest_of_line, ! Remainer of command line including this token quote_mark; ! Quote mark to be used in parse_result parse_result := result_so_far; rest_of_line := current_token + substr (eve$x_command_line, eve$x_command_index, (eve$x_command_length - eve$x_command_index) + 1); if index (rest_of_line, '"') = 0 then quote_mark := '"'; else if index (rest_of_line, "'") = 0 then quote_mark := "'"; else ! double the quote marks in string quote_mark := '"'; rest_of_line := eve$double_quotes (rest_of_line); endif; endif; parse_result := parse_result + quote_mark + rest_of_line + quote_mark + ")"; return (parse_result); endprocedure; ! Page 104 ! The main command line parsing procedure. Returns a VAXTPU command string. ! Parses Eve commands, which call procedures whose names start with "eve_". ! Commands can be typed with or without parentheses and quotation marks. ! Multi-word commands like fill_paragraph may be typed with a space instead ! of an underscore. Defaults are provided so that procedures will prompt ! for missing arguments (prompting varies too much for effective ! centralization). ! ! Parameters: ! ! line_to_parse Eve command string - input procedure eve$parse (line_to_parse) local parse_result, ! String containing VAXTPU command to execute current_token, ! String currently being processed uppercase_token, ! Uppercase version of current_token expanded_token, ! String with all candidate commands choice_token, ! Current item from expanded_token command_token, ! Eve command name, with underscores command_name, ! Eve command name, without underscores choices, ! Subset of expanded_token that match how_many_choices, ! How many items in choices possible_completion, ! String containing first n words of command completion, ! First possible_completion ambiguous_completion, ! True if possible_completion is not unique no_more_words, ! True when all words in command name parsed reusing_token, ! True if lookahead found an argument instead ! of part of a command name this_buffer, ! Current buffer arguments, ! Number of arguments expected for this command which_argument; ! Number of argument currently being processed on_error ! Trap messages with tpu$_nonames and tpu$_multiplenames endon_error; eve$x_command_line := line_to_parse; eve$x_command_index := 1; eve$x_command_length := length (eve$x_command_line); eve$x_ambiguous_parse := 0; eve$x_argument_type := eve$kt_null; parse_result := eve$kt_null; command_token := eve$kt_null; command_name := eve$kt_null; expanded_token := eve$kt_null; uppercase_token := eve$kt_null; erase (eve$choice_buffer); ! Get command name - since commands may have spaces, this can ! involve parsing several tokens ! Handle first token separately, outside the loop, for easier diagnostics ! and handling eve_ prefix current_token := eve$get_token; if current_token = eve$kt_null then message ("No command given"); return (eve$kt_null); endif; if not eve$x_is_symbol then message (fao ("Unrecognized command: !AS", current_token)); return (eve$kt_null); endif; uppercase_token := current_token; change_case (uppercase_token, upper); if substr (uppercase_token, 1, 4) <> "EVE_" then uppercase_token := "EVE_" + uppercase_token; endif; this_buffer := current_buffer; ! Loop for parsing command token loop expanded_token := expand_name (uppercase_token, procedures); if expanded_token = eve$kt_null then if parse_result <> eve$kt_null then reusing_token := 1; exitif 1; else ! Usually will get leading space due to "Command: " prompt message (fao ("Don't understand command: !AS", substr (eve$x_command_line, 1, eve$x_command_index - 1))); return (eve$kt_null); endif; endif; how_many_choices := 0; ambiguous_completion := 0; completion := eve$kt_null; choices := eve$kt_null; ! Move to choice buffer and loop through the choices. eve$expand_to_choices (expanded_token); loop exitif mark (none) = end_of (eve$choice_buffer); choice_token := current_line; how_many_choices := how_many_choices + 1; if uppercase_token = choice_token then ! found an exact match parse_result := choice_token; endif; possible_completion := eve$complete (uppercase_token, choice_token); if possible_completion = choice_token then no_more_words := 1; endif; if how_many_choices = 1 then completion := possible_completion; else if completion <> possible_completion then ambiguous_completion := 1; endif; endif; move_vertical (1); endloop; eve$strip_choices (4); position (this_buffer); translate (eve$choice_buffer, " ", "_"); if parse_result = uppercase_token then reusing_token := 0; exitif 1; else if how_many_choices = 1 then parse_result := expanded_token; else if ambiguous_completion then eve$display_choices (fao ("Ambiguous command name: !AS", substr (eve$x_command_line, 1, eve$x_command_index - 1))); return (eve$kt_null); else if no_more_words then parse_result := completion; reusing_token := 0; exitif 1; endif; endif; endif; endif; ! Get next token and try to build command current_token := eve$get_token; if current_token = eve$kt_null then if parse_result <> eve$kt_null then reusing_token := 1; exitif 1; else eve$display_choices (fao ("Ambiguous command name: !AS", substr (eve$x_command_line, 1, eve$x_command_index - 1))); return (eve$kt_null); endif; else uppercase_token := completion + "_" + current_token; change_case (uppercase_token, upper); endif; endloop; command_token := substr (parse_result, 5, 1); change_case (parse_result, lower); command_token := command_token + substr (parse_result, 6, length (parse_result) - 5); command_name := command_token; translate (command_name, " ", "_"); ! Check for arguments that this command expects arguments := 1; loop exitif expand_name ("eve$arg" + str (arguments) + "_" + command_token, variables) = eve$kt_null; arguments := arguments + 1; endloop; arguments := arguments - 1; ! Since execute can only take 132 character strings, Eve command ! names can only be (132 - 30) = 102 characters long. ! If arguments = 0 or eve$arg* is uninitialized, eve$x_argument_type ! has already been initialized to the null string. if arguments > 0 then execute ("eve$x_argument_type:=eve$arg1_" + command_token); endif; ! Get second token - if it's an open paren, get the next token. ! Parsing command name may have stopped on real 2nd token, so check. if not reusing_token then current_token := eve$get_token; endif; which_argument := 0; if arguments > 0 then parse_result := parse_result + "("; endif; ! Loop to handle arguments, in 4 steps: ! 1) If last argument, check for closing punctuation and return ! 2) If last token, handle defaults for remaining arguments ! 3) Handle the argument ! 4) Get the next token loop ! If last argument, handle closing punctuation and return if which_argument = arguments then if (current_token = "\") or (current_token = "|") then current_token := eve$get_token; endif; if current_token = eve$kt_null then if arguments > 0 then parse_result := parse_result + ")"; endif; return (parse_result); else if arguments = 0 then message (fao ("!AS does not take any arguments", command_name)); else message (fao ("!AS takes only !SL argument!%S", command_name, arguments)); endif; return (eve$kt_null); endif; endif; ! If there are no more tokens, handle default arguments. ! All Eve functions will prompt appropriately when they get the ! null string or negative numbers as arguments if current_token = eve$kt_null then loop exitif which_argument = arguments; which_argument := which_argument + 1; execute ("eve$x_argument_type:=eve$arg" + str (which_argument) + "_" + command_token); change_case (eve$x_argument_type, lower); if eve$x_argument_type = "string" then parse_result := parse_result + '""'; else if eve$x_argument_type = "integer" then parse_result := parse_result + 'eve$k_no_arg+0'; else message (fao ("Argument type !AS must be integer or string", eve$x_argument_type)); return (eve$kt_null); endif; endif; if which_argument < arguments then parse_result := parse_result + ","; endif; endloop; parse_result := parse_result + ")"; return (parse_result); endif; ! Handle current argument which_argument := which_argument + 1; execute ("eve$x_argument_type:=eve$arg" + str (which_argument) + "_" + command_token); change_case (eve$x_argument_type, lower); if eve$x_argument_type = "string" then if eve$x_is_quoted_string then parse_result := parse_result + current_token; else if which_argument = arguments then parse_result := eve$add_final_string (parse_result, current_token); return (parse_result); else loop exitif eve$x_command_index > eve$x_command_length; exitif index (eve$x_token_separators, substr (eve$x_command_line, eve$x_command_index, 1)) > 0; current_token := current_token + eve$get_token; endloop; current_token := eve$double_quotes (current_token); parse_result := parse_result + '"' + current_token + '"'; endif; endif; else if eve$x_argument_type = "integer" then if eve$x_is_number then translate (current_token, "1", "l"); parse_result := parse_result + current_token; else message (fao ("!AS expects a number for argument !SL", command_name, which_argument)); return (eve$kt_null); endif; else message (fao ("Argument type !AS must be integer or string", eve$x_argument_type)); return (eve$kt_null); endif; endif; ! Get next token current_token := eve$get_token; if current_token = "," then current_token := eve$get_token; parse_result := parse_result + ","; else if which_argument < arguments then parse_result := parse_result + ","; endif; endif; endloop; endprocedure; ! Page 105 ! The procedures EVE$INIT_KEY and EVE$CLEAR_KEY are no longer needed ! in order to guarantee that user keys are not superseded by EVE key ! definitions. Key maps are used for that purpose now. The following ! key maps are used by EVE: ! ! TPU$KEY_MAP_LIST Only key map list used ! Contains the following maps: ! ! EVE$USER_KEYS Defined by EVE's DEFINE_KEY ! and LEARN/REMEMBER commands ! EVE$VT100_KEYS / EVE$VT200_KEYS EVE's numeric pad keys ! EVE$STANDARD_KEYS EVE's non-pad keys ! ! The EVE$... key maps are reserved for use by EVE. Users and layered ! products should add their own maps to the list. ! EVE always puts its maps at the end of the list, so user keys always ! supersede EVE keys. ! Page 106 ! Define standard key definitions - control keys, arrow keys, e- and f- keys. ! This procedure is not available from the Eve after initialization. procedure eve$standard_keys ! Leading spaces in comment field are used to indicate Eve-supplied key ! definitions - do not use in user-written key definitions ! Set up the key maps eve$init_variables; eve$x_user_keys := create_key_map ("eve$user_keys"); eve$x_vt100_keys := create_key_map ("eve$vt100_keys"); eve$x_vt200_keys := create_key_map ("eve$vt200_keys"); eve$x_standard_keys := create_key_map ("eve$standard_keys"); ! First create the vt100 key-pad define_key ("eve_next_screen", kp0, " next_screen", eve$x_vt100_keys); define_key ("eve_previous_screen", period, " previous_screen", eve$x_vt100_keys); define_key ("eve_change_mode", enter, " change_mode", eve$x_vt100_keys); define_key ("eve_move_left", kp1, " move_left", eve$x_vt100_keys); define_key ("eve_move_down", kp2, " move_down", eve$x_vt100_keys); define_key ("eve_move_right", kp3, " move_right", eve$x_vt100_keys); define_key ("eve_move_up", kp5, " move_up", eve$x_vt100_keys); define_key ("eve_erase_word", comma, " erase_word", eve$x_vt100_keys); define_key ("eve_select", kp7, " select", eve$x_vt100_keys); define_key ("eve_remove", kp8, " remove", eve$x_vt100_keys); define_key ("eve_insert_here", kp9, " insert_here", eve$x_vt100_keys); define_key ("eve_move_by_line", minus, " move_by_line", eve$x_vt100_keys); define_key ("eve_find ('')", pf1, " find", eve$x_vt100_keys); define_key ("eve_help ('keypad')", pf2, " help", eve$x_vt100_keys); define_key ("eve_change_direction", pf3, " change_direction", eve$x_vt100_keys); define_key ("eve_do ('')", pf4, " do", eve$x_vt100_keys); ! next create the vt200 numeric keypad define_key ("copy_text ('0')", kp0, " typing", eve$x_vt200_keys); define_key ("copy_text ('.')", period, " typing", eve$x_vt200_keys); define_key ("eve_return", enter, " return", eve$x_vt200_keys); define_key ("copy_text ('1')", kp1, " typing", eve$x_vt200_keys); define_key ("copy_text ('2')", kp2, " typing", eve$x_vt200_keys); define_key ("copy_text ('3')", kp3, " typing", eve$x_vt200_keys); define_key ("copy_text ('4')", kp4, " typing", eve$x_vt200_keys); define_key ("copy_text ('5')", kp5, " typing", eve$x_vt200_keys); define_key ("copy_text ('6')", kp6, " typing", eve$x_vt200_keys); define_key ("copy_text (',')", comma, " typing", eve$x_vt200_keys); define_key ("copy_text ('7')", kp7, " typing", eve$x_vt200_keys); define_key ("copy_text ('8')", kp8, " typing", eve$x_vt200_keys); define_key ("copy_text ('9')", kp9, " typing", eve$x_vt200_keys); define_key ("copy_text ('-')", minus, " typing", eve$x_vt200_keys); ! Create the function keys (common to all keyboards) ! Arrow keys define_key ("eve_move_left", left, " move_left", eve$x_standard_keys); define_key ("eve_move_right", right, " move_right", eve$x_standard_keys); define_key ("eve_move_down", down, " move_down", eve$x_standard_keys); define_key ("eve_move_up", up, " move_up", eve$x_standard_keys); ! VT200 editing keypad keys define_key ("eve_find ('')", e1, " find", eve$x_standard_keys); define_key ("eve_insert_here", e2, " insert_here", eve$x_standard_keys); define_key ("eve_remove", e3, " remove", eve$x_standard_keys); define_key ("eve_select", e4, " select", eve$x_standard_keys); define_key ("eve_previous_screen", e5, " previous_screen", eve$x_standard_keys); define_key ("eve_next_screen", e6, " next_screen", eve$x_standard_keys); ! Top row function keys define_key ("eve_exit", f10, " exit", eve$x_standard_keys); define_key ("eve_change_direction", f11, " change_direction", eve$x_standard_keys); define_key ("eve_move_by_line", f12, " move_by_line", eve$x_standard_keys); define_key ("eve_erase_word", f13, " erase_word", eve$x_standard_keys); define_key ("eve_change_mode", f14, " change_mode", eve$x_standard_keys); define_key ("eve_help ('keypad')", help, " help", eve$x_standard_keys); define_key ("eve_do ('')", do, " do", eve$x_standard_keys); ! Keys on main typing array define_key ("eve_delete", del_key, " delete", eve$x_standard_keys); define_key ("eve_tab", tab_key, " tab", eve$x_standard_keys); define_key ("eve_return", ret_key, " return", eve$x_standard_keys); !<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>> ! the following key definitions have been removed or modified define_key ("eve_recall", key_name('l', shift_key), " recall", eve$x_standard_keys); !define_key ("eve_end_of_line", ctrl_e_key, " end_of_line", eve$x_standard_keys); define_key ("eve_start_of_line", ctrl_h_key, " start_of_line", eve$x_standard_keys); !>>>>>>>>>>>>>>>end evelse change<<<<<<<<<<<<<<<<<<<<<<<<<< define_key ("eve_remember", ctrl_r_key, " remember", eve$x_standard_keys); define_key ("eve_erase_start_of_line", ctrl_u_key, " erase_start_of_line", eve$x_standard_keys); define_key ("eve_quote", ctrl_v_key, " quote", eve$x_standard_keys); define_key ("eve_refresh", ctrl_w_key, " refresh", eve$x_standard_keys); define_key ("eve_exit", ctrl_z_key, " exit", eve$x_standard_keys); define_key ("eve_space", key_name (' '), " space", eve$x_standard_keys); remove_key_map(eve$x_key_map_list, "tpu$key_map", ALL); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_user_keys); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_vt200_keys); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_standard_keys); !<<<<<<<<<<<<<<<<<<<<< evelse change >>>>>>>>>>>>>>>>>>>>>>>> ! add the key_map for lse add_key_map(eve$x_key_map_list, eve$kt_last, "tpu$key_map"); !>>>>>>>>>>>>>>>>>> end evelse change <<<<<<<<<<<<<<<<<<<<<<< endprocedure ! Page 107 ! Define numeric keypad layout for VT200 series keyboards procedure eve$vt200_keys on_error endon_error; remove_key_map(eve$x_key_map_list, eve$x_vt100_keys, ALL); remove_key_map(eve$x_key_map_list, eve$x_vt200_keys, ALL); remove_key_map(eve$x_key_map_list, eve$x_standard_keys, ALL); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_vt200_keys); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_standard_keys); eve$x_vt200_keypad := TRUE; endprocedure; ! Page 108 ! Define numeric keyboard layout for VT100 series keyboards procedure eve$vt100_keys on_error endon_error; remove_key_map(eve$x_key_map_list, eve$x_vt100_keys, ALL); remove_key_map(eve$x_key_map_list, eve$x_vt200_keys, ALL); remove_key_map(eve$x_key_map_list, eve$x_standard_keys, ALL); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_vt100_keys); add_key_map(eve$x_key_map_list, eve$kt_last, eve$x_standard_keys); eve$x_vt200_keypad := FALSE; endprocedure; ! Make sure there is a DO key either on DO or PF4 procedure eve$init_do_key on_error return; endon_error; if not eve$x_vt200_keypad then if lookup_key (PF4, program, eve$x_user_keys) <> 0 then if eve$insist_y_n("PF4 is not DO. Redefine PF4 as DO? ") then define_key ("eve_do ('')", PF4, " do", eve$x_user_keys); endif; endif; endif; endprocedure ! Page 109 ! Initialization procedures ! Initialization for user's own variables procedure tpu$local_init eve$init_procedure; endprocedure; ! Page 110 ! Procedure used to create an Eve system buffer. Returns the new buffer. ! ! Parameters: ! ! new_buffer_name String for name of new buffer - input ! new_eob_text String for eob_text of new buffer - input procedure eve$init_buffer (new_buffer_name, new_eob_text) local new_buffer; ! New buffer new_buffer := create_buffer (new_buffer_name); set (eob_text, new_buffer, new_eob_text); set (no_write, new_buffer); set (system, new_buffer); return (new_buffer); endprocedure; ! Page 111 ! Routines to do copy_texts in INSERT or OVERSTRIKE mode without perturbing ! the current mode ! ! Routine to insert text ! ! Parameter: ! ! the_text String to be inserted procedure eve$insert_text(the_text) ! Copy_text in insert mode LOCAL old_mode; ! Used to hold the current mode old_mode := get_info(current_buffer, eve$kt_mode); set(INSERT, current_buffer); copy_text(the_text); set(old_mode, current_buffer); endprocedure; ! Routine to overstrike text ! ! Parameter: ! ! the_text Text string to overstrike with procedure eve$overstrike_text(the_text) ! Copy_text in overstrike mode LOCAL old_mode; ! Used to hold the current mode old_mode := get_info(current_buffer, eve$kt_mode); set(OVERSTRIKE, current_buffer); copy_text(the_text); set(old_mode, current_buffer); endprocedure; ! Page 112 ! Routine to translate a buffer name to a buffer pointer ! ! Inputs: ! ! buffer_name String containing the buffer name ! procedure eve$find_buffer(buffer_name) ! Find a buffer by name local the_buffer, ! Used to hold the buffer pointer the_name; ! A read/write copy of the name the_name := buffer_name; change_case(the_name, UPPER); the_buffer := get_info(buffers, eve$kt_first); loop exitif (the_buffer = 0); exitif (the_name = get_info(the_buffer, eve$kt_name)); the_buffer := get_info(buffer, "next"); endloop; return the_buffer; endprocedure ! Page 113 ! Routine to unmap a window only if it is mapped ! ! Parameter: ! ! window_to_unmap Window that needs unmapping procedure eve$unmap_if_mapped (window_to_unmap) !Unmap a window if (get_info (window_to_unmap, eve$kt_buffer) <> 0) then unmap (window_to_unmap); endif; endprocedure ! Map the named window to the named buffer. The map is ! done if get_info(window,eve$kt_buffer) <> named buffer. ! ! Parameter: ! ! window_to_map Window that needs mapping ! buffer_to_map And the buffer to map it to procedure eve$map_if_not_mapped (window_to_map, buffer_to_map) !Map window if (get_info (window_to_map, eve$kt_buffer) <> buffer_to_map) then map (window_to_map, buffer_to_map); endif; endprocedure ! Page 114 ! Hooks for layered products ! ! Procedure to create buffer global areas and other buffer specific stuff ! procedure eve$create_buffer_globals(the_buffer) endprocedure ! Dispatch to package specific parsers, should there be any EVE-layered ! products built in. ! procedure eve$parser_dispatch(the_command) eve$process_command(the_command); endprocedure ! Procedure to call the initialization procedures for the various packages ! procedure eve$package_init endprocedure ! Page 115 ! INITIALIZATION PROCEDURE procedure eve$init_windows ! Create all the necessary default windows screen_length := get_info (screen, eve$kt_visible_length); ! Create windows for top and bottom halves of the screen ! Top window may be one line longer than bottom window. eve$main_window_length := screen_length - 2; eve$bottom_window_length := eve$main_window_length / 2; eve$top_window_length := eve$main_window_length - eve$bottom_window_length; if get_info(eve$main_window, eve$kt_type) <> window then !<<<<<<<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! lse has already created a main window so use it instead.... delete (lse$main_window); lse$main_window := create_window (1, eve$main_window_length, on); eve$main_window := lse$main_window; ! eve$main_window := create_window (1, eve$main_window_length, on); endif; if get_info(eve$top_window, eve$kt_type) <> window then !<<<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! lse has already defined a top_window so let's use it instead of ! creating a new one delete (lse$top_window); lse$top_window := create_window (1, eve$top_window_length, on); eve$top_window := lse$top_window; ! eve$top_window := create_window (1, eve$top_window_length, on); !>>>>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<<<<< endif; if get_info(eve$bottom_window, eve$kt_type) <> window then !<<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! since lse has a bottom window let's use it instead of creating a ! new one delete (lse$bottom_window); lse$bottom_window := create_window (eve$top_window_length + 1, eve$bottom_window_length, on); eve$bottom_window := lse$bottom_window; ! eve$bottom_window := ! create_window (eve$top_window_length + 1, eve$bottom_window_length, on); endif; !>>>>>>>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<<<<< ! Create the info window (used for HELP and SHOW) using the same size as ! the main window if get_info(info_window, eve$kt_type) <> window then info_window := create_window (1, eve$main_window_length, on); endif; ! Create the choice window--used by parser to display choices when a name is ! ambiguous. It overlays the last few lines of the main or bottom window. if get_info(eve$choice_window, eve$kt_type) <> window then eve$choice_window := create_window (eve$main_window_length + 1 - eve$x_choice_window_length, eve$x_choice_window_length, on); endif; ! Create the command window, prompt window and prompt area, all of which ! go on the next to the last line. if get_info(eve$command_window, eve$kt_type) <> window then eve$command_window := create_window (screen_length - 1, 1, off); endif; if get_info(eve$prompt_window, eve$kt_type) <> window then !<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>> ! lse has already created a prompt window so let's redo it... delete (lse$$prompt_window); lse$$prompt_window := create_window (screen_length - 1, 1, off); eve$prompt_window := lse$$prompt_window; ! eve$prompt_window := create_window (screen_length - 1, 1, off); endif; !>>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<< set (prompt_area, screen_length - 1, 1, reverse); ! Create the message window at the very bottom of the screen. if get_info(message_window, eve$kt_type) <> window then !<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>> ! since lse has already created a message window let's not create ! another. Just assign eve's message window to lse's. delete (lse$message_window); message_window := create_window (screen_length, 1, off); lse$message_window := message_window; set (video, message_window, bold); !>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<< endif; endprocedure procedure eve$init_buffers local line_editing_mode; ! Line editing mode of terminal ! Create all the necessary default buffers ! Create a main buffer !<<<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>>> ! since lse has already created a main buffer comment out the following !main_buffer := create_buffer ("Main"); main_buffer := lse$main_buffer; eve$create_buffer_globals(main_buffer); if eve$main_window <> 0 then map (eve$main_window, main_buffer); set (margins, main_buffer, eve$x_default_left_margin, get_info (eve$main_window, eve$kt_width) - eve$x_default_right_margin); endif; !set (eob_text, main_buffer, "[End of file]"); !>>>>>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<< ! Command buffer eve$command_buffer := eve$init_buffer ("Commands", eve$kt_null); set (permanent, eve$command_buffer); line_editing_mode := get_info(screen, "line_editing"); if line_editing_mode <> 0 then set (line_editing_mode, eve$command_buffer); else set (overstrike, eve$command_buffer);! for VMS V4 line-editing compatibility endif; set (reverse, eve$command_buffer); ! for VMS V4 line-editing compatibility if eve$command_window <> 0 then map (eve$command_window, eve$command_buffer); endif; ! Prompt buffer !<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>> ! lse has already created a prompt buffer, so use it instead! eve$prompt_buffer := lse$$prompt_buffer; !eve$prompt_buffer := eve$init_buffer ("Prompts", eve$kt_null); !>>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<< if eve$prompt_window <> 0 then set (video, eve$prompt_window, reverse); endif; ! Message buffer--mapped to the message window ! ! No message buffer if /NODISPLAY if get_info(command_line, 'display') then ! <<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>> ! message buffer should point to the lse$message_buffer ! if you want eve to have its own message buffer then comment ! out the first line and uncomment the second.... ! message_buffer := get_info (lse$message_window, eve$kt_buffer); ! delete lse's message buffer to remove it from the buffer list delete (message_buffer); message_buffer := eve$init_buffer ("Messages", eve$kt_null); ! >>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<< if message_window <> 0 then map (message_window, message_buffer); endif; endif; ! Get the help buffer, and show buffer, and DCL buffer help_buffer := eve$init_buffer ("Help", eve$kt_null); !<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! comment out the following line to get lse's $show buffer !show_buffer := eve$init_buffer ("Show", eve$kt_null); !>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<<<<<< eve$dcl_buffer := eve$init_buffer ("DCL", eve$kt_null); ! Buffer used by parser to display choices when a name is ambiguous eve$choice_buffer := eve$init_buffer ("Choices", eve$kt_null); set (permanent, eve$choice_buffer); ! Now do the paste buffer !<<<<<<<<<<<<<<<<<<<<<< wpelse change >>>>>>>>>>>>>>>>>>>>>>>>>>>>> ! lse has already created a cut and paste buffer so use it instead paste_buffer := lse$$cut_paste_buffer; !paste_buffer := eve$init_buffer ("Insert Here", "[End of Insert Here buffer]"); !>>>>>>>>>>>>>>>>>>>> end wpelse change <<<<<<<<<<<<<<<<<<<<<<<<< endprocedure procedure eve$init_files local output_file_name, ! Original output file name parsed_output_file_name, ! Full filespec for output file input_file_name_only, ! No node, disk, directory, or version opening_journal, ! True when we get to the journal stuff journal_error; ! True if can't parse journal file name on_error if error = tpu$_parsefail then if opening_journal = 0 then ! error in parsing output file message (fao ("Don't understand output file name: !AS", output_file_name)); else ! error in parsing journal file journal_error := 1; endif; endif; endon_error; ! Create a buffer using get_file input_file := get_info (command_line, eve$kt_file_name); input_file_name_only := file_parse (input_file," "," ",NAME) + file_parse (input_file," "," ",TYPE); eve$x_this_window := eve$main_window; if eve$main_window <> 0 then position(eve$main_window); if input_file = eve$kt_null then eve$set_status_line (current_window); else eve$enter_command_window; copy_text ("buffer " + input_file_name_only); eve$exit_command_window; if (current_buffer <> main_buffer) and (current_window = eve$main_window) then delete (main_buffer); endif; endif; else position (main_buffer); endif; ! The output file should be written to the current directory by default ! unless there is another directory specified in the output_file_name. ! We also DON'T want the node, device or directory of the input file, just ! the name. if get_info (command_line, "output") <> 1 then set (no_write, current_buffer); message (fao ("File !AS is opened read only", output_file_name)); else output_file_name := get_info (command_line, eve$kt_output_file); if output_file_name <> eve$kt_null then parsed_output_file_name := file_parse (output_file_name, input_file_name_only); if parsed_output_file_name <> eve$kt_null then if eve$is_wildcard (parsed_output_file_name) then message (fao ("Can't create file: !AS", parsed_output_file_name)); else set (output_file, current_buffer, parsed_output_file_name); ! Want this buffer to be considered modified so it will ! be written on exit - for use especially with mail/edit split_line; append_line; endif; endif; else set (output_file, current_buffer, input_file); endif; endif; ! Start journalling !opening_journal := 1; !if (get_info (command_line, "journal") = 1) and ! (get_info (command_line, "read_only") <> 1) then ! journal_file := get_info (command_line, "journal_file"); ! input_file_name_only := file_parse (get_info (current_buffer, ! eve$kt_file_name), ! eve$kt_null, eve$kt_null, name); ! if input_file_name_only = eve$kt_null then ! input_file_name_only := "tpu.tjl"; ! else ! input_file_name_only := input_file_name_only + ".tjl"; ! endif; ! journal_file := ! file_parse (journal_file, input_file_name_only); ! if journal_file = eve$kt_null then ! journal_file := ! file_parse (eve$kt_null, input_file_name_only); ! endif; ! if journal_error then ! message (fao ("Don't understand journal file name: !AS", journal_file)); ! else ! journal_open (journal_file); ! endif; !endif; endprocedure procedure eve$init_settings ! Turn off message headers (facility, severity, id) set (message_flags, 1); ! Turn on bell for broadcast messages set (bell, broadcast, on); ! Get rid of shift key - VAXTPU doesn't save result of a set (shift_key) set (shift_key, key_name (pf1, shift_key)); ! Try to determine if terminal is VT100 or VT200 on VMS V3 and V4. ! If terminal is eight-bit, edit-mode, ansi crt, then assume it ! is a VT200 series terminal. The VT200 bindings are saved in the ! section file by default. The following determines whether there ! is a VT200 out there and if not sets the VT100 numeric keypad. if not get_info (screen, "vt200") then ! If he say VT200, believe him. if get_info (screen, "vk100") then ! Special case the GiGi eve$vt100_keys; else if not ((get_info (screen, "eightbit")) and ! How VT2xx's looked (get_info (screen, "ansi_crt")) and ! on VMS V3, just in (get_info (screen, "edit_mode"))) then ! case some-one is eve$vt100_keys; ! still set-up that way endif; endif; endif; eve$init_do_key; endprocedure procedure eve$init_procedure ! Initialize our variables, windows, buffers, files etc. eve$init_variables; eve$init_windows; eve$init_buffers; eve$init_files; eve$init_settings; ! Call the initialization routines for any layered products eve$package_init; ! Indicate that initialization is complete eve$x_starting_up := 0; endprocedure; ! Page 116 ! Define the keys, save the section, and quit. eve$standard_keys; compile ("procedure eve$standard_keys endprocedure");