!+ ! eag_windows.tpu !- PROCEDURE EVE_SET_MAPPING ! Enable main keyboard digits as mapping keys on_error endon_error if eag$x_map_on = 1 then message ('Mapping is already enabled'); return; endif; eag$x_map_on := 1; eag_defined_shift := 0; if ( eveplus_g_shift_key = ctrl_y_key ) then eag_shift_key := pf1; eveplus_key ( "eve_find(eve$x_target)", pf1, "Gold", "eag_shift_key" ); eag_users_shift_key := EVEPLUS_SET_SHIFT_KEY ( pf1 ); eag_defined_shift := 1; endif; eveplus_key ( 'eve_show_map', key_name('0',shift_key),"Show Map Window", 'eag$x_show_map'); eveplus_key ( 'eve_map_buffer("1")',key_name('1',shift_key),"Show Buffer #1", 'eag$x_map1'); eveplus_key ( 'eve_map_buffer("2")',key_name('2',shift_key),"Show Buffer #2", 'eag$x_map2'); eveplus_key ( 'eve_map_buffer("3")',key_name('3',shift_key),"Show Buffer #3", 'eag$x_map3'); eveplus_key ( 'eve_map_buffer("4")',key_name('4',shift_key),"Show Buffer #4", 'eag$x_map4'); eveplus_key ( 'eve_map_buffer("5")',key_name('5',shift_key),"Show Buffer #5", 'eag$x_map5'); eveplus_key ( 'eve_map_buffer("6")',key_name('6',shift_key),"Show Buffer #6", 'eag$x_map6'); eveplus_key ( 'eve_map_buffer("7")',key_name('7',shift_key),"Show Buffer #7", 'eag$x_map7'); eveplus_key ( 'eve_map_buffer("8")',key_name('8',shift_key),"Show Buffer #8", 'eag$x_map8'); eveplus_key ( 'eve_map_buffer("9")',key_name('9',shift_key),"Show Buffer #9", 'eag$x_map9'); ENDPROCEDURE ! EVE_SET_MAPPING PROCEDURE EVE_SET_NOMAPPING ! Disable main keyboard digits as mapping keys on_error endon_error if eag$x_map_on = 0 then message ("Mapping keys are already disabled"); return; endif; eag$x_map_on := 0; if ( eag_defined_shift = 1 ) then eag_users_shift_key := EVEPLUS_SET_SHIFT_KEY ( ctrl_y_key ); eag_defined_shift := 0; endif; eveplus_restore_key ( 'eag$x_show_map'); eveplus_restore_key ( 'eag$x_map1'); eveplus_restore_key ( 'eag$x_map2'); eveplus_restore_key ( 'eag$x_map3'); eveplus_restore_key ( 'eag$x_map4'); eveplus_restore_key ( 'eag$x_map5'); eveplus_restore_key ( 'eag$x_map6'); eveplus_restore_key ( 'eag$x_map7'); eveplus_restore_key ( 'eag$x_map8'); eveplus_restore_key ( 'eag$x_map9'); eag_show_window ( 0 ); message ('Mapping keys disabled.'); ENDPROCEDURE ! EVE_SET_NOMAP PROCEDURE EVE_SET_EAG_WINDOW_KEYS ! Enable extra window keys on_error endon_error if eag$x_windows_on = 1 then message ('EAG window keys are already enabled'); return; endif; eag$x_windows_on := 1; if eag$x_map_on = 0 then eve_set_mapping; else eag_defined_shift := 0; if ( eveplus_g_shift_key = ctrl_y_key ) then eag_shift_key := pf1; eveplus_key ( "eve_find(eve$x_target)", pf1, "Gold", "eag_shift_key" ); eag_users_shift_key := EVEPLUS_SET_SHIFT_KEY ( pf1 ); eag_defined_shift := 1; endif; endif; ! File Access eveplus_key ( "eve_write_file('')", key_name (enter, shift_key), "Write File", "eag$x_write_file_key" ); eveplus_key ( "eve_write_file(read_line('Name?'))", key_name (comma, shift_key), "Write New file", "eag$x_write_new_key" ); eveplus_key ( "eag_get_file", enter, "Get file", "eag$x_get_file_key" ); if expand_name ( 'eve_destroy_buffer', procedures ) <> eve$x_null then eveplus_key ("eve_destroy_buffer(get_info(current_buffer,'name'))", key_name ( del_key, shift_key ), "Opps!", "eag$x_opps_key" ); endif; ! Window Manipulation eveplus_key ( "eve_toggle_number_of_windows", key_name (kp3, shift_key), "Toggle # windows", "eag$x_toggle_win_key" ); eveplus_key ( "eve_other_window", kp3, "Other window", "eag$x_other_win_key" ); ! Message Window Access eveplus_key ( "eve_mess_up", key_name(up,shift_key), "Message Window UP", "eag$x_mess_up_key" ); eveplus_key ( "eve_mess_down", key_name(down,shift_key), "Message Window Down", "eag$x_mess_down_key" ); ! Horizontal scrolling eveplus_key ( "eag_shift(eag_shift_amount)", key_name (right,shift_key), "Shift right", "eag$x_shift_right_key" ); eveplus_key ("eag_shift(-eag_shift_amount)", key_name (left,shift_key), "Shift left", "eag$x_shift_left_key" ); ENDPROCEDURE ! EVE_SET_EAG_WINDOW_KEYS PROCEDURE EVE_SET_NOEAG_WINDOW_KEYS ! Disable extra window keys on_error endon_error if eag$x_windows_on = 0 then message ("EAG window keys are already disabled"); return; endif; eag$x_windows_on := 0; message ('EAG window keys disabled.'); eveplus_restore_key ("eag$x_write_file_key" ); eveplus_restore_key ("eag$x_write_new_key" ); eveplus_restore_key ("eag$x_get_file_key" ); if expand_name ( 'eve_destroy_buffer', procedures ) <> eve$x_null then eveplus_restore_key ( "eag$x_opps_key" ); endif; eveplus_restore_key ("eag$x_toggle_win_key" ); eveplus_restore_key ("eag$x_other_win_key" ); eveplus_restore_key ("eag$x_mess_up_key" ); eveplus_restore_key ("eag$x_mess_down_key" ); eveplus_restore_key ("eag$x_shift_right_key"); eveplus_restore_key ("eag$x_shift_right_key"); ENDPROCEDURE; PROCEDURE EVE_SHOW_MAP ! Show/update the map window, toggle LOCKING it ON if current_buffer = eag_map_buffer then if eag_map_lock = 0 then eag_map_lock := 1; message( "Map window is now set ON" ); else eag_map_lock := 0; message( "Map window is now set OFF" ); position ( eve$x_this_window ); endif; endif; eag_show_map; if get_info ( eag_map_window, 'type') = window then position ( eag_map_window ); endif; ENDPROCEDURE; ! EVE_SHOW_MAP PROCEDURE EAG_GET_FILE ! Get a file and update the window map if current_window = eag_map_window then position ( eve$x_this_window ); endif; eve_get_file (''); if eag_map_lock = 1 then eag_show_map; endif; ENDPROCEDURE; PROCEDURE EVE_MESS_UP ! Scroll the message window up scroll(message_window,-1); ENDPROCEDURE; ! EVE_MESS_UP PROCEDURE EVE_MESS_DOWN ! Scroll the message window down scroll(message_window,1); ENDPROCEDURE; ! EVE_MESS_DOWN PROCEDURE EAG_SHIFT ( AMT ) ! Shift a window to the left or right LOCAL lmar, rmar, rn; lmar := get_info (current_window, 'shift_amount' ); if lmar + amt < 0 then message ("You're already at the left border of this buffer"); else lmar := lmar + amt; rmar := lmar + get_info (current_window, 'width' ); lmar := lmar + 1; ln := str(lmar); rn := str(rmar); message ( ln+'<---------------------->'+rn); shift (current_window,amt); endif; ENDPROCEDURE; ! EAG_SHIFT PROCEDURE EVE_TOGGLE_NUMBER_OF_WINDOWS ! Toggle 1/2 windows, show map SET (SCREEN_UPDATE, OFF); ! For speed and to avoid confusion if eve$x_number_of_windows = 1 then eve_two_windows; else eve_one_window; endif; if eag_map_lock = 1 then eag_show_map; endif; SET (SCREEN_UPDATE, ON); ! For speed and to avoid confusion ENDPROCEDURE; PROCEDURE EVE_MAP_BUFFER( BUFFER_ARG ) ! Map the numbered buffer to window ! This routine will convert its argument into an integer. It will then ! count through the non-system buffers till it finds the corresponding ! buffer and map that buffer to the current window. LOCAL buffer_var, ! Holds buffer variable buffer_number, ! Argument converted to a number buffer_save, ! Buffer on entry to this routine buffer_count; ! Index/counter for counting loop if current_window = eag_map_window then position ( eve$x_this_window ); endif; buffer_save := current_buffer; buffer_number := int ( buffer_arg ); if buffer_arg <> 0 then buffer_count := 0; buffer_var := GET_INFO(BUFFER, "FIRST"); LOOP exitif buffer_var = 0; if get_info (buffer_var, "system") = 0 then buffer_count := buffer_count + 1; endif; exitif buffer_count = buffer_number; buffer_var := GET_INFO(BUFFER, "NEXT"); ENDLOOP; if buffer_count = buffer_number then if buffer_var <> current_buffer then eve_buffer ( GET_INFO(buffer_var, "NAME" ) ); endif; else eve_get_file ( read_line ( 'name? ' )); endif; endif; if eag_map_lock = 0 then if buffer_save = eag_map_buffer then buffer_save := current_buffer; eag_show_window ( 0 ); position ( buffer_save ); endif; else buffer_save := current_buffer; eag_show_map; position ( buffer_save ); endif; ENDPROCEDURE PROCEDURE EAG_SHOW_MAP ! Builds a new map buffer based on available info ! This routine will erase and re-build the contents of the map buffer to ! reflect the current non-system buffers that exist. It will then call ! eag_show_window to insure that the buffers are properly displayed. LOCAL saved_position, ! Holds text position on entry prev_largest_string,! Holds the last value of largest buffer name string buffer_name, ! Holds string name of buffer buffer_var, ! Holds buffer variable buffer_number, ! Argument converted to a number buffer_count; ! Index/counter for counting loop on_error endon_error; saved_position := current_window; if (get_info ( eag_map_buffer, "type") = unspecified) or (eag_map_buffer = 0) then eag_map_buffer := eve$init_buffer ("Buffers", eve$x_null); endif; if get_info(eag_map_window,'buffer') <> eag_map_buffer then if (get_info ( eag_map_window, 'type') = window) AND (get_info ( eag_map_buffer, 'type') = buffer) then map (eag_map_window, eag_map_buffer); endif; endif; eag_map_width := get_info ( screen, "width" ); set ( width, current_window, eag_map_width ); LOOP ! Till we paint a map buffer that's accurate erase ( eag_map_buffer ); position ( beginning_of ( eag_map_buffer )); if (eag_min_prefered_string > eag_largest_string) then eag_curr_min_string := eag_largest_string; else eag_curr_min_string := eag_min_prefered_string; endif; prev_largest_string := eag_largest_string; eag_largest_string := 0; eag_buf_per_line := ( eag_map_width + 4 ) / ( eag_curr_min_string + 4 ); eag_map_lines := eag_buffer_count / eag_buf_per_line; if ( eag_buffer_count <> eag_map_lines * eag_buf_per_line ) then eag_map_lines := eag_map_lines +1; endif; eag_buf_per_line := eag_buffer_count / eag_map_lines; if (eag_buffer_count <> eag_buf_per_line * eag_map_lines) then eag_buf_per_line := eag_buf_per_line +1; endif; eag_slot_size := ( (eag_map_width + 4) / eag_buf_per_line ) - 4; buffer_var := GET_INFO(BUFFER, "FIRST"); buffer_count := 0; line_count := 1; buffer_line_index := 0; LOOP exitif buffer_var = 0; if get_info (buffer_var, "system") = 0 then buffer_count := buffer_count + 1; if buffer_line_index >= eag_buf_per_line then split_line; buffer_line_index := 1; line_count := line_count + 1; else buffer_line_index := buffer_line_index + 1; endif; if buffer_line_index <> 1 then copy_text ( ' ' ); endif; copy_text ( str(buffer_count) + ' '); buffer_name := GET_INFO( buffer_var, "NAME" ); if ( length ( buffer_name ) > ( eag_slot_size - 1 ) ) then copy_text( substr( buffer_name, 1, ( eag_slot_size -1 ))); else copy_text( substr( buffer_name, 1, length( buffer_name ))); copy_text( substr( eag_blank_string, 1, (eag_slot_size - 1 - (length( buffer_name ))))); endif; if ( length ( buffer_name )) > ( eag_largest_string ) then eag_largest_string := length ( buffer_name ); endif; endif; buffer_var := GET_INFO(BUFFER, "NEXT"); ENDLOOP; exitif (buffer_count = eag_buffer_count) AND (prev_largest_string >= eag_largest_string); eag_buffer_count := buffer_count; ENDLOOP; eag_show_window ( eag_map_lines ); if get_info ( saved_position, 'type') = window then position (saved_position); endif; ENDPROCEDURE PROCEDURE EAG_SHOW_WINDOW ( NEEDED_LINES ) ! Adjusts map window if needed. ! This procedure checks, and if necessary, creates/adjusts/deletes the ! map window so as to display the specified number of map_window lines. ! If the argument is 0, the map window will go away. If a size change ! is needed, this routine adjusts the size of the lower EVE window and ! the EVE main window to compensate for the size of the map_window, keeping ! track of the buffers kept in the EVE windows as well. LOCAL save_window, ! Temporary storage for current window buffer_var, ! Temporary storage for buffer variable adjustment; ! Needed adjustment to map window save_window := current_window; adjustment := eag_map_window_size - needed_lines; if (needed_lines) = 0 then ! Get rid of map window if (get_info (eag_map_window, "type") = window ) then unmap ( eag_map_window ); delete ( eag_map_window ); save_window := eve$x_this_window; endif; endif; if adjustment <> 0 then ! we must adjust the size of the mapping window SET (SCREEN_UPDATE, OFF); ! For speed and to avoid confusion if adjustment > 0 then ! Window is too big if (needed_lines) <> 0 then ! Window exists adjust_window ( eag_map_window, adjustment, 0); endif; endif; if eve$x_number_of_windows = 1 then position (eve$main_window); adjust_window ( eve$main_window, 0, adjustment); eve_two_windows; adjust_window ( eve$bottom_window, 0, adjustment); eve_one_window; else position (eve$bottom_window); buffer_var := current_buffer; adjust_window ( eve$bottom_window, 0, adjustment); position (eve$top_window); eve_one_window; adjust_window ( eve$main_window, 0, adjustment); eve_two_windows; position (eve$bottom_window); eve_buffer ( GET_INFO( buffer_var, "NAME" ) ); endif; if adjustment < 0 then ! window is too small (might not exist) if (get_info (eag_map_window, "type") = window ) then adjust_window ( eag_map_window, adjustment, 0); else eag_map_window := create_window ( ((screen_length - needed_lines) - 1), needed_lines, off); map (eag_map_window, eag_map_buffer); endif; endif; SET (SCREEN_UPDATE, ON); endif; position ( beginning_of ( eag_map_buffer)); eag_map_window_size := needed_lines; position (save_window); ENDPROCEDURE; PROCEDURE EAG$INIT ! Called from tpu$init - has on_error statement. on_error ! ON_ERROR statements are not permitted in an endon_error; ! eveplus tpu$init, so tpu$init calls eag$init. if expand_name ( 'eag$x_write_file_key', variables ) <> eve$x_null then eag$x_map_on := 1; ! Windows are enabled eag$x_windows_on := 1; ! Mapping is enabled as a result else eag$x_windows_on := 0; ! Window keys are not enabled but mapping? if expand_name ( 'eag$x_show_map', variables ) <> eve$x_null then eag$x_map_on := 1; else eag$x_map_on := 0; endif; endif; if eag_map_lock = 1 then eag_show_map; endif; ENDPROCEDURE; PROCEDURE TPU$LOCAL_INIT; eag$init; if (get_info ( eag_shift_amount, "type") = unspecified) then eag_shift_amount := 40; endif; if (get_info ( eag_map_lock, "type") = unspecified) then eag_map_lock := 0; endif; eag_buffer_count := 1; eag_largest_string := 99; eag_blank_string := ' '; eag_min_prefered_string := 16; eag_map_window_size := 0; ENDPROCEDURE; tpu$local_init; ! Define VMS line editing keys for Eve/Evg !+ ! EVE_VMS_LINE_EDITING.TPU !- ! ! This is a set of definitions for defining and removing VMS line editing ! keys for EVEPlus. PROCEDURE EVE_SET_VMS_LINE_EDITING ! Define VMS line editing keys vle$x_keypadset := 1; set(informational,off); eveplus_key("eve_change_mode",ctrl_a_key, "change_mode (Toggle insert/overstrike)","vle_ctrl_a_key"); eveplus_key("vle_move_left",ctrl_d_key,"move_left","vle_ctrl_d_key"); eveplus_key("vle_move_right",ctrl_f_key,"move_right","vle_ctrl_f_key"); if expand_name('eve_set_edt_keypad',procedures) = eve$x_null then eveplus_key("eve_start_of_line", ctrl_h_key, "EDT BACKSPACE (start_of_line)", "vle_ctrl_h_key"); eveplus_key("eve_start_of_line", bs_key, "EDT BACKSPACE (start_of_line)", "vle_bs_key"); eveplus_key("eve_start_of_line", f12, "EDT BACKSPACE (start_of_line)", "vle_f12_key"); ! ! NOTE: The ctrl_x_key definitions will never get executed, they're just ! here to define a comment for dynamic help. The ctrl_x is NEVER ! passed to TPU, EVE, or EVEPlus. Rather, the VMS Terminal Driver ! will flush the type-ahead buffer, and pass a CTRL_U to the process ! upon receipt of a CTRL_X. ! eveplus_key("eve_erase_start_of_line",ctrl_x_key, "EDT CTRL_U (delete_to_beginning_of_line)","vle_ctrl_x_key"); eveplus_key("eve_erase_start_of_line",ctrl_u_key, "EDT CTRL_U (delete_to_beginning_of_line)","vle_ctrl_u_key"); eveplus_key("eve_erase_previous_word",ctrl_j_key, "EDT CTRL_J (erase prev word)","vle_ctrl_j_key"); eveplus_key("eve_erase_previous_word",f13, "EDT LINEFEED (erase_previous_word)","vle_f13_key"); else eveplus_key("eee_backspace",ctrl_h_key,"EDT BACKSPACE (start_of_line)", "vle_ctrl_h_key"); eveplus_key("eee_backspace",bs_key,"EDT BACKSPACE (start_of_line)", "vle_bs_key"); eveplus_key("eee_backspace",f12,"EDT BACKSPACE (start_of_line)", "vle_f12_key"); eveplus_key("eee_delete_beg_line",ctrl_x_key, "EDT CTRL_U (delete_to_beginning_of_line)","vle_ctrl_x_key"); eveplus_key("eee_delete_beg_line",ctrl_u_key, "EDT CTRL_U (delete_to_beginning_of_line)","vle_ctrl_u_key"); eveplus_key("eee_del_beg_word",ctrl_j_key,"EDT ctrl_j (erase_previous_word)", "vle_ctrl_j_key"); eveplus_key("eee_del_beg_word",f13,"EDT LINEFEED (erase_previous_word)", "vle_f13_key"); endif; set(informational,on); message(". . . Done!"); ENDPROCEDURE; PROCEDURE EVE_SET_NOVMS_LINE_EDITING ! Remove VMS line editing keys if vle$x_keypadset = 1 then vle$x_keypadset := 0; message("Removing VMS Line Editing Keys . . ."); set(informational,off); eveplus_restore_key("vle_ctrl_a_key"); eveplus_restore_key("vle_ctrl_d_key"); eveplus_restore_key("vle_ctrl_f_key"); eveplus_restore_key("vle_ctrl_h_key"); eveplus_restore_key("vle_bs_key"); eveplus_restore_key("vle_f12_key"); eveplus_restore_key("vle_ctrl_x_key"); eveplus_restore_key("vle_ctrl_u_key"); eveplus_restore_key("vle_ctrl_j_key"); eveplus_restore_key("vle_f13_key"); set(informational,on); message(". . . Done!"); else message("Can't remove key definitions - no older definitions available."); endif; ENDPROCEDURE; PROCEDURE VLE_MOVE_LEFT ! Move left (ctrl_d) if (current_window = eve$command_window) and (current_column <= (eve$x_command_prompt_length + 1)) then return; else eve_move_left; endif; ENDPROCEDURE; PROCEDURE VLE_MOVE_RIGHT ! Move right (ctrl_f) if (current_character = eve$x_null) or (mark(none) = end_of(current_buffer)) then return; else eve_move_right; endif; ENDPROCEDURE; ! Note: ! ! If you wish to have the VMS Line Editing keys enabled as the default, ! uncomment the procedure call below. ! eve_set_vms_line_editing; ! Define VMS line editing keys for Eve/Evg !+ ! NUMBER_LINES.TPU - Routine to add line numbers to a buffer !- PROCEDURE EVE_NUMBER_LINES local line_number; line_number := 1; position(beginning_of(current_buffer)); loop if (((line_number / 250) * 250) = line_number) then message("Numbering line " + str(line_number)); endif; exitif (mark(none) = end_of(current_buffer)); eveplus_insert_text(fao("!6UL ", line_number)); line_number := line_number + 1; move_horizontal(-current_offset); move_vertical(1); endloop; ENDPROCEDURE; !+ ! WHAT.TPU - Displays a message with the current line number, ! total number of lines in the file, and the percentage. !- ! PROCEDURE EVE_WHAT_LINE ! What line am I on? local this_position, ! marker - current position start_of_buffer, ! marker - beginning of current buffer this_line_position, ! marker - position at start of this_line total_lines, ! integer - total lines in buffer high_line, ! integer - high line limit for binary search low_line, ! integer - low line limit for binary search this_line, ! integer - line number of current guess percent; ! integer - percent of way through buffer ! Initialization this_position := mark (none); start_of_buffer := beginning_of (current_buffer); total_lines := get_info (current_buffer, "record_count") + 1; high_line := total_lines; if this_position = end_of (current_buffer) then low_line := total_lines; else low_line := 1; endif; ! Binary search loop exitif high_line - low_line <= 1; this_line := low_line + ((high_line - low_line) / 2); position (start_of_buffer); move_vertical (this_line - 1); if mark (none) > this_position then high_line := this_line; else low_line := this_line; if mark (none) = this_position then high_line := this_line; endif; endif; endloop; ! TPU will truncate numbers on division; make it round instead percent := (((low_line * 1000) / total_lines)+5)/10; ! Display message and return to original position message (fao ("You are on line !SL out of !SL (!SL%)", low_line, total_lines, percent)); position (this_position); ENDPROCEDURE; !+ ! MATCHING.TPU - Routine to automatically insert close parentheses etc. !- procedure eve_set_matching(the_arg) ! Turn on electric open parens LOCAL the_key, the_keys, ptr; the_keys := the_arg; if (the_keys = "") then the_keys := read_line("Match what characters: "); endif; ptr := 1; loop exitif (ptr > length(the_keys)); the_key := substr(the_keys, ptr, 1); if (index(eveplus_matchable_open, the_key) <> 0) then define_key("eveplus_insert_matched", key_name(the_key), " typing"); else message('"' + the_key + '" is not matchable'); return; endif; ptr := ptr + 1; endloop; endprocedure; procedure eve_set_nomatching(the_arg) ! Turn off electric open parens LOCAL the_key, the_keys, ptr; the_keys := the_arg; if (the_keys = "") then the_keys := read_line("Remove matching for what charcters: "); endif; ptr := 1; loop exitif (ptr > length(the_keys)); the_key := substr(the_keys, ptr, 1); if (index(eveplus_matchable_open, the_key) <> 0) then undefine_key(key_name(the_key)); else if (index(eveplus_matchable_close, the_key) = 0) then message('"' + the_key + '" is not matchable'); return; endif; endif; ptr := ptr + 1; endloop; endprocedure; procedure eveplus_insert_matched ! Insert the two caharcters LOCAL the_key, which; the_key := ascii(last_key); which := index(eveplus_matchable_open, the_key); if (which <> 0) then eveplus_insert_text(the_key); eveplus_insert_text(substr(eveplus_matchable_close, which, 1)); move_horizontal(-1); else message("That key isn't matchable."); return; endif; endprocedure ! Insert the second of two match characters (close character), and display ! the line with the matching open character in the message window, with ! the open character highlighted. Try to handle quotes by skipping over ! strings when encountered - doesn't work perfectly if already in a quoted ! strings. Doesn't handle comments. ! Parameters: ! ! match_chars String - characters to be matched; e.g. "()" ! quote_chars String - quote characters; e.g. "'""" procedure eveplus_match (match_chars, quote_chars) ! Find the open paren local this_position, ! Marker - current cursor position right_matches, ! Integer - number of opens to close all_chars, ! String - match_chars + quote_chars match_pattern, ! Pattern - any (all_chars) match_position, ! Marker - current position during searches this_quote; ! String - current quote character on_error ! Just continue endon_error; if length (match_chars) <> 2 then message ("Must have 2 characters to match"); return; endif; copy_text (substr (match_chars, 2, 1)); this_position := mark (none); right_matches := 1; move_horizontal (-1); all_chars := match_chars + quote_chars; match_pattern := any (all_chars); loop match_position := search (match_pattern, reverse); exitif match_position = 0; position (match_position); if index (quote_chars, current_character) > 0 then this_quote := current_character; move_horizontal (-1); match_position := search (this_quote, reverse); exitif match_position = 0; position (match_position); else if current_character = substr (match_chars, 1, 1) then right_matches := right_matches - 1; else right_matches := right_matches + 1; endif; endif; exitif right_matches = 0; endloop; if right_matches = 0 then eveplus_display_line; else message ("No matching parentheses found"); endif; position (this_position); endprocedure; ! Internal routine for eveplus_match ! Display current line in message window, with current position highlighted procedure eveplus_display_line ! Display the matching line local this_position, ! Marker - current cursor position this_line, ! String - current line start_of_line, ! Marker - Start of current line this_offset; ! Integer - offset of this_position this_position := mark (blink); this_offset := current_offset; move_horizontal (- current_offset); start_of_line := mark (none); move_horizontal (length (current_line)); this_line := create_range (start_of_line, mark (none), none); message (this_line); position (end_of (message_buffer)); move_vertical (-1); move_horizontal (this_offset); eveplus_this_position := mark (blink); position (this_position); endprocedure; procedure eve_set_flashing(arg) ! Turn on flashing parens LOCAL the_key, the_keys, key_number, ptr; eve$prompt_string(arg, the_keys, "Flash what characters: ", "No flashing set"); ptr := 1; loop exitif (ptr > length(the_keys)); the_key := substr(the_keys, ptr, 1); key_number := index(eveplus_matchable_close, the_key); if (key_number <> 0) then define_key ("eveplus_match ('" + substr(eveplus_matchable_open, key_number, 1) + the_key + "', '""''')", key_name (the_key), " typing"); else message('"' + the_key + '" is not matchable'); return; endif; ptr := ptr + 1; endloop; endprocedure; procedure eve_set_noflashing(arg) ! Turn off falshing parens LOCAL the_key, the_keys, ptr; eve$prompt_string(arg, the_keys, "Remove flashing for what charcters: ", "No flashing characters removed"); ptr := 1; loop exitif (ptr > length(the_keys)); the_key := substr(the_keys, ptr, 1); if (index(eveplus_matchable_close, the_key) <> 0) then undefine_key(key_name(the_key)); else if (index(eveplus_matchable_open, the_key) = 0) then message('"' + the_key + '" is not matchable'); return; endif; endif; ptr := ptr + 1; endloop; endprocedure; procedure tpu$local_init ! Package initialization eve$arg1_set_matching := 'string'; eve$arg1_set_nomatching := 'string'; eve$arg1_set_flashing := 'string'; eve$arg1_set_noflashing := 'string'; eveplus_matchable_open := "([{<«'`"""; eveplus_matchable_close := ")]}>»''"""; endprocedure; tpu$local_init;