procedure KHF$FIND_ALL_MODULE_IDENT return "V03-001"; endprocedure; !++ ! KHF$FIND_ALL.TPU ! ! This module comprises a set of procedures which are analogous to ! EVE's FIND and WILDCARD FIND commands, but which display ALL ! occurrences of the found string or pattern. The procedures make use ! of, and depend upon, EVE's internal procedures, such as ! Eve$$Build_Pattern, through Eve$Get_Find_Target, to correctly assess ! the user's input and construct the appropriate pattern variable. ! However, the user is prompted from these procedures, if necessary, ! so that improper prompt strings (for this application) are not ! issued from Eve$Get_Find_Target. Further, the SEARCH_QUIETLY ! built-in is called here and so avoids the need to call ! Eve$Find_Target at all. ! ! By default, only lines in which the target pattern is found are ! displayed, while all other lines in the buffer are hidden. The ! method used is to set the DISPLAY_VALUE for all records to be less ! than that of the current window, making them invisible, and then ! setting the DISPLAY_VALUE of any records containing the search ! string to be equal that of the window, thus making them visible. In ! order to prevent unwanted and unexpected edits to invisible records, ! all records in the buffer are initially set to MODIFIABLE,OFF; then ! records containing the target are set MODIFIABLE,ON allowing the ! user to make edits to the displayed lines. ! ! The user may change whether lines which don't contain the search ! string or pattern are hidden, or whether all lines continue to be ! displayed (with the found ranges highlighted), through the commands ! CHANGE HIDE, SET FIND ALL HIDE, and SET FIND ALL NOHIDE. If ! "nohide" is in effect, the DISPLAY_VALUE and MODIFIABLE attributes ! are left unchanged and there are no restrictions on editing. ! ! This module includes modified versions of Eve$Search and Eve_Reset, ! taken from EVE$CORE.TPU. If the user were to do a FIND or REPLACE ! while lines are hidden, following a FIND ALL but before making all ! lines in the buffer visible again, a found string could easily occur ! on an invisible line. To avoid confusing the user, Eve$Search now ! skips over those found ranges which contain "unmodifiable_records", ! as returned from Get_Info. Eve_Reset was modified so that a RESET ! command would clear the FIND ALL ranges and show all lines in the ! buffer, via a call to Khf$Find_All_Fin. ! ! ! Note: It might be preferable to detect visibility rather than ! modifiability, but Get_Info returns visibility only for ! _marks_, not _ranges_. Thus, in using visibility of a ! mark, there would be the possibility of returning a ! range that is at least partly hidden. This package ! takes the more conservative approach. ! ! ! This module includes modified versions of Eve$Move_By_Screen, taken ! from EVE$WINDOWS.TPU, and several Eve_Move_xxx procedures, taken ! from EVE$EDIT.TPU. When some lines in a buffer are hidden ! following, for example, FIND ALL, the default Move_Vertical used by ! Eve$Move_By_Screen, and both Move_Vertical and Move_Horizontal used ! by the various Eve_Move_xxx procedures, is likely to leave the ! current editing position on an invisible line (for the latter ! procedures, the effect may be limited to having the "bound cursor" ! turned on). The editing point is subsequently repositioned to a ! visible line by EVE's "detached cursor" routine and an annoying ! message is displayed. Furthermore, the vertical movement is based ! on buffer lines, not on visible screen lines, which makes the actual ! amount of movement irregular and unpredictable. It is even possible ! that there will be NO change in the editing point at all. ! Eve$Move_By_Line was modified to use the TPU built-in Scroll in ! conjunction with Cursor_Vertical if, and only if, the buffer has ! hidden lines. The various Eve_Move_xxx procedures were modified to ! use Cursor_Vertical if the result of Move_Horizontal or ! Move_Vertical left the position on an invisible record, and a ! possible reposition to the beginning or end of line. ! ! ! This module also includes modified versions of several Eve$Edt_xxx ! procedures. As is the case for the Eve_Move_xxx procedures, the ! Eve$Edt_xxx procedures use of Move_Horizontal or Move_Vertical can ! result in the editing point falling on a hidden line. The ! modifications ensure that the editing point is on a visible lines ! before exiting these procedures. ! ! Note: If it is known that the Eve$Edt_xxx procedures will ! _not_ be used, the modified versions at the end of this ! file may be removed without ill effect on anything else ! in this module. ! ! ! Note: All modifications to EVE procedures are marked by "!KHF" ! in the right margin. ! ! ! This module is compatible with EVE versions V2.6 through V3.1. ! ! ! New procedures in this file: ! ! Eve_Find_All Displays all occurrences of a string ! Eve_Wildcard_Find_All Displays all occurrences of a pattern ! Eve_Set_Find_All_Hide Hide lines w/o a match (default) ! Eve_Set_Find_All_NoHide Show all lines (matches highlighted) ! Eve_Change_Hide Toggles between Hide and NoHide ! Khf$Find_All Does the work for the above procedures ! Khf$Find_All_Fin Restores buffer to normal display ! value and modifiability ! Khf$$Hidden_Lines Does a buffer have hidden lines? ! Khf$$Invisible_Line Is the current line invisible? ! ! ! Modified procedures extracted from EVE$CORE.TPU (V03-035): ! ------------ ! ! Eve$Search Search (including leading w/s) ! Eve_Reset RESET command ! ! ! Modified procedures extracted from EVE$EDIT.TPU (V03-026): ! ------------ ! ! Eve_Move_By_Line Move to start of line ! Eve_Move_By_Word Move to start of next/prev word ! Eve_Move_Down Move down one row (free and bound cursor) ! Eve_Move_Left Move left one column (free and bound cursor) ! Eve_Move_Right Move right one column (free and bound cursor) ! Eve_Move_Up Move up one row (free and bound cursor) ! Eve_Top TOP ! ! ! Modified procedures extracted from EVE$WINDOWS.TPU (V03-012): ! --------------- ! ! Eve$Move_By_Screen Next/prev screen subprocedure ! ! ! Modified procedures extracted from EVE$EDT.TPU (V03-004): ! ----------- ! ! Eve$Edt_Backspace Backspace ! Eve$Edt_Eol Move to end of line ! Eve$Edt_Char Character ! Eve$Edt_Line Line ! Eve$Edt_Section Scroll screen ! ! ! Acknowledgements: ! ! The motivation to write this package came from Jonathan ! Ridler, , who was ! looking for an EVE procedure to do what XEDIT's & KEDIT's ! "ALL" command does. ! ! The key to making it work (at all!) came from Tom ! Williams, , who pointed out the ! DISPLAY_VALUE parameter to TPU's SET(RECORD_ATTRIBUTE) ! built-in. Without that, the functionality found here ! could not have been accomplished. ! ! ! Author/Date: K.H. Fairfield, 05-Aug-1994 ! ! Revisions: !-- procedure KHF$FIND_ALL_MODULE_INIT ! ------------------------ khf$x_find_all_hide := TRUE; ! If FALSE, display _all_ lines khf$x_found_ranges := Create_Array; ! Array indexed by _buffer_ to hold ! the array of bolded found ranges khf$x_hiding_lines := Create_Array; ! Flags whether we're displaying only ! selected lines (TRUE), indexed ! by buffer !+ ! The following global variables, present in EVE V3.1, are not present ! in EVE V2.6. In order to use this module in EVE V2.6, they are set ! equal to the value of the equivalent variable or constant found in ! that earlier version, but only if they are undefined at initialization. !- If eve$x_whitespace = TPU$K_UNSPECIFIED Then eve$x_whitespace := eve$kt_whitespace; Endif; If eve$x_scrolling = TPU$K_UNSPECIFIED Then eve$x_scrolling := ON; Endif; Endprocedure; ! KHF$FIND_ALL_MODULE_INIT !-----------------------------New Procedures-------------------------------- Procedure Eve_Find_All ! Find and display all occurences of a string ! ------------ (target) ! The string to find. Local the_target, ! Local copy of search string saved_position, ! Save the current position status, ! Returned from Eve$Get_Find_Target how_exact, ! Ditto idx; ! Loop counter On_Error [TPU$_CONTROLC]: Khf$Find_All_Fin; Eve$$Restore_Position (saved_position); Eve$Learn_Abort; Abort; [OTHERWISE]: Khf$Find_All_Fin; Eve$$Restore_Position (saved_position); Endon_Error; If CURRENT_WINDOW = eve$prompt_window Then Eve$Learn_Abort; Return (FALSE); ! already a find(?) going on Endif; If Not Eve$Declare_Intention (eve$k_action_reposition) Then Return (FALSE); Endif; saved_position := Mark (FREE_CURSOR); !+ ! Toggle back to showing all lines in the buffer and clear out ! highlighted ranges. !- Khf$Find_All_Fin; !+ ! If the user responds to the prompt with a null string, make sure we go ! back to showing all lines in the buffer unconditionally. !- If Not Eve$Prompt_String (target, the_target, "Find All: ", "Nothing to find.") Then Return (FALSE); Endif; !+ ! Get the search string into the global variable eve$x_target, and also ! find out whether the search will need to be EXACT or not. !- status := Eve$Get_Find_Target (the_target, how_exact, 0); If status = EVE$K_SUCCESS Then status := Khf$Find_All (how_exact); Else If status = EVE$K_ASYNC_PROMPTING Then Return (TRUE); ! This is for dialog box prompting. Endif; ! It's not implemented, but we're ready. Endif; Return (status); Endprocedure; ! Eve_Find_All Procedure Eve_Wildcard_Find_All ! Find and display all occurences of a pattern ! --------------------- (target) ! The patter to find. Actually a string which ! will be translated by Eve$$Build_Pattern ! through Eve$Get_Find_Target. Local the_target, ! Local copy of search string saved_position, ! Save the current position status, ! Returned from Eve$Get_Find_Target how_exact, ! Ditto idx; ! Loop counter On_Error [TPU$_CONTROLC]: Khf$Find_All_Fin; Eve$$Restore_Position (saved_position); Eve$Learn_Abort; Abort; [OTHERWISE]: Khf$Find_All_Fin; Eve$$Restore_Position (saved_position); Endon_Error; If CURRENT_WINDOW = eve$prompt_window Then Eve$Learn_Abort; Return (FALSE); ! already a find(?) going on Endif; If Not Eve$Declare_Intention (eve$k_action_reposition) Then Return (FALSE); Endif; saved_position := Mark (FREE_CURSOR); !+ ! Toggle back to showing all lines in the buffer and clear out ! highlighted ranges. !- Khf$Find_All_Fin; !+ ! If the user responds to the prompt with a null string, make sure we go ! back to showing all lines in the buffer unconditionally. !- If Not Eve$Prompt_String (target, the_target, "Wildcard Find All: ", "Nothing to find.") Then Return (FALSE); Endif; !+ ! Get the search string/pattern into the global variable eve$x_target, and ! also find out whether the search will need to be EXACT or not. !- status := Eve$Get_Find_Target (the_target, how_exact, 2); If status = EVE$K_SUCCESS Then status := Khf$Find_All (how_exact); Else If status = EVE$K_ASYNC_PROMPTING Then Return (TRUE); ! This is for dialog box prompting. Endif; ! It's not implemented, but we're ready. Endif; Return (status); Endprocedure; ! Eve_Wildcard_Find_All Procedure Eve_Set_Find_All_Hide ! Hide lines which don't contain ! --------------------- ! eve$x_target (default) Local idx, ! Index for steping through the range array max_idx, ! High index of range array range_array; ! Array of highlighted ranges for this buffer !+ ! Check whether this buffer currently has a set of found_ranges. If so, ! and if it's not already hiding lines, hide all lines in the buffer, ! and then step through the foudn ranges and make each corresponding ! record visible. !- If Get_Info (khf$x_found_ranges {CURRENT_BUFFER}, "type") = ARRAY Then If Not khf$x_hiding_lines {CURRENT_BUFFER} Then khf$x_hiding_lines {CURRENT_BUFFER} := TRUE; Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, DISPLAY_VALUE, -1); Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, MODIFIABLE, OFF); range_array := khf$x_found_ranges {CURRENT_BUFFER}; max_idx := Get_Info (range_array, "high_index"); idx := 1; Loop Exitif (idx > max_idx); Exitif (range_array {idx} = TPU$K_UNSPECIFIED); Set (RECORD_ATTRIBUTE, range_array {idx}, DISPLAY_VALUE, 0); Set (RECORD_ATTRIBUTE, range_array {idx}, MODIFIABLE, ON); idx := idx+1; Endloop; If Get_Info (Mark (FREE_CURSOR), "display_value") < 0 Then If Get_Info (CURRENT_BUFFER, "direction") = FORWARD Then Cursor_Vertical (0); Else Cursor_Vertical (-1); Endif; If eve$x_bound_cursor Then Position (TEXT); Endif; Endif; Endif; Endif; khf$x_find_all_hide := TRUE; Message ( "[WILDCARD] FIND ALL will now hide lines which don't contain a match."); return (TRUE); Endprocedure; ! Eve_Set_Find_All_Hide Procedure Eve_Set_Find_All_NoHide ! Don't hide lines which don't contain ! ----------------------- ! eve$x_target (default) !+ ! If the CURRENT_BUFFER has hidden lines, make them visible and modifiable ! (but leave the highlighted ranges alone). !- If Khf$$Hidden_Lines (CURRENT_BUFFER) Then khf$x_hiding_lines {CURRENT_BUFFER} := FALSE; Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, DISPLAY_VALUE, 0); Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, MODIFIABLE, ON); Eve$Position_In_Middle (Mark (FREE_CURSOR)); Endif; khf$x_find_all_hide := FALSE; Message ( "[WILDCARD] FIND ALL will now show all lines, matches will be highlighted."); return (TRUE); Endprocedure; ! Eve_Set_Find_All_NoHide Procedure Eve_Change_Hide ! Toggle the Hide/NoHide setting ! --------------- If khf$x_find_all_hide Then Return (Eve_Set_Find_All_NoHide); Else Return (Eve_Set_Find_All_Hide); Endif; Endprocedure; ! Eve_Change_Hide Procedure Khf$Find_All ! Find and display only those lines containing ! ------------ the target pattern or string. (how_exact) ! Keyword used by SEARCH, either EXACT or NOEXACT. Local this_range, ! Range returned from SEARCH_QUIETLY. nrange, ! Used as index into found_ranges. max_ranges, ! Size of found_ranges. found_ranges, ! Local array to hold found ranges. temp_array, ! Used when extending found_ranges. idx, ! An array index. direction, ! Direction setting of current buffer. saved_position, ! Where we started. Return here if target not found. saved_line, ! Record number of current line. this_line, ! Record number of found range. this_delta, ! Number of lines from saved line to this_line. best_delta, ! Number of lines from saved_line to closest range. best_idx; ! Index for the closest range. direction := Get_Info (CURRENT_BUFFER, "direction"); saved_position := Mark (FREE_CURSOR); saved_line := Get_Info (saved_position, "record_number"); Position (BUFFER_BEGIN); !+ ! See if we can find at least one occurrence of the target. If not, ! issue a message and return. !- this_range := Search_Quietly (eve$x_target, FORWARD, how_exact); If this_range = 0 Then If Get_Info (eve$x_target, "type") = STRING Then Eve$Message (EVE$_STRNOTFOUND, 0, eve$x_target); Else Eve$Message (EVE$_STRNOTFOUND, 0, eve$x_printable_target); Endif; Position (saved_position); Return (0); Endif; Set (TIMER, ON, "Searching..."); !+ ! We've found at least one occurrence of eve$x_target. Set the whole ! buffer to not be displayed, then set this record so it will display. ! Also, set all records in the buffer to NOT be modifiable to protect ! the user from unintentional modifications to invisible lines. This ! record, and subsequent found-ranges, will be individually set to be ! modifiable. ! ! Note that we're depending on the default _window_ display value to ! be zero. !- If khf$x_find_all_hide Then Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, DISPLAY_VALUE, -1); Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, MODIFIABLE, OFF); khf$x_hiding_lines {CURRENT_BUFFER} := TRUE; Endif; !+ ! Initialize found_ranges array, and the variables for determining closest ! range, to the first found range. !- max_ranges := 10; found_ranges := Create_Array (max_ranges); idx := 1; Loop Exitif idx > max_ranges; found_ranges {idx} := 0; idx := idx + 1; Endloop; best_delta := Get_Info (CURRENT_BUFFER, "record_count") + 1; best_idx := 1; ! Position to the first found range by default nrange := 1; Loop Exitif this_range = 0; !+ ! Store and BOLD (eve$x_found_highlighting) the found range, and set the ! current record to be displayed. Also set this range to be modifiable. !- found_ranges {nrange} := Create_Range (Beginning_of (this_range), End_of (this_range), eve$x_found_highlighting); If khf$x_find_all_hide Then Set (RECORD_ATTRIBUTE, found_ranges {nrange}, DISPLAY_VALUE, 0); Set (RECORD_ATTRIBUTE, found_ranges {nrange}, MODIFIABLE, ON); Endif; !+ ! Check to see if this range is closer to saved_position than any others ! found so far. !- this_line := Get_Info (Beginning_of (found_ranges {nrange}), "record_number"); If direction = FORWARD Then this_delta := this_line - saved_line; Else this_delta := saved_line - this_line; Endif; If (this_delta >= 0) And (this_delta < best_delta) Then best_delta := this_delta; best_idx := nrange; Endif; !+ ! Get ready for the next search. !- Position (End_of (found_ranges {nrange})); Move_Horizontal (1); !+ ! Extend the range array if required. !- nrange := nrange + 1; If nrange > max_ranges ! Extend the array Then temp_array := Create_Array (max_ranges * 2); idx := 1; Loop Exitif idx > max_ranges; temp_array {idx} := found_ranges {idx}; idx := idx + 1; Endloop; max_ranges := max_ranges * 2; found_ranges := temp_array; Endif; !+ ! Search for the next occurrence of eve$x_target. ! Note: we have already postitioned to the end of the previously ! found range. !- this_range := Search_Quietly (eve$x_target, FORWARD, how_exact); Endloop; !+ ! All done, store found_ranges in khf$x_found_ranges, and position to the ! closest one. !- If khf$x_find_all_hide Then Position (found_ranges {best_idx}); Else Eve$Position_In_Middle (found_ranges {best_idx}); Endif; khf$x_found_ranges {CURRENT_BUFFER} := found_ranges; Set (TIMER, OFF); Return (TRUE); Endprocedure; ! Khf$Find_All Procedure Khf$Find_All_Fin ! Restore a buffer to showing all lines, etc. ! ---------------- !+ ! Restore all records' display value to the default, zero. !- Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, DISPLAY_VALUE, 0); !+ ! If lines were hidden, scroll the window so the current editing position ! is not at the bottom of the page. !- If Khf$$Hidden_Lines (CURRENT_BUFFER) Then Eve$Position_In_Middle (Mark (FREE_CURSOR)); Endif; !+ ! Set khf$x_found_ranges for the current buffer to zero. This deletes ! any previously existing ranges stored in that index, and clears the ! highlighting of the text (by destroying the associated ranges). !- khf$x_found_ranges {CURRENT_BUFFER} := 0; khf$x_hiding_lines {CURRENT_BUFFER} := FALSE; !+ ! Restore the buffer's records' modifiable setting to ON, but don't do ! it for system buffers. (This should really be gated by some test on ! entry to Khf$Find_All. However, a BUFFER set MODIFIABLE, OFF supercedes ! the RECORD_ATTRIBUTE setting, so we should be OK.) !- If Not Get_Info (CURRENT_BUFFER, "system") Then Set (RECORD_ATTRIBUTE, CURRENT_BUFFER, MODIFIABLE, ON); Endif; Return; Endprocedure; ! Khf$Find_All_Fin Procedure Khf$$Hidden_Lines ! Does the buffer have hidden lines? ! ----------------- (the_buffer) ! Buffer to check If khf$x_hiding_lines {the_buffer} <> TPU$K_UNSPECIFIED Then If khf$x_hiding_lines {the_buffer} Then Return (TRUE); Endif; Endif; Return (FALSE); Endprocedure; ! Khf$$Hidden_Lines Procedure Khf$$Invisible_Line ! Is the current line invisible? ! ------------------- If khf$x_hiding_lines {CURRENT_BUFFER} <> TPU$K_UNSPECIFIED Then If khf$x_hiding_lines {CURRENT_BUFFER} And (Get_Info (Mark (NONE), "display_value") < Get_Info (CURRENT_WINDOW, "display_value")) Then Return (TRUE); Endif; Endif; Return (FALSE); Endprocedure; ! Khf$$Invisible_Line !------------------------Modified EVE Procedures------------------------- ! EVE$CORE.TPU Page 18 procedure eve$search ! Search (including leading w/s) (the_target, ! \ the_direction, ! >-all as per the SEARCH built-in exactness, ! / leading_whitespace,! if true include all leading w/s replacing) ! if true allow a match at the current location ! 0 - FIND Skip current location ! 1 - REPLACE Allow a match here ! 2 - WILDCARD FIND Skip current location local the_range, on_range, saved_mark; on_error [TPU$_CONTROLC]: eve$$restore_position (saved_mark); eve$learn_abort; abort; [OTHERWISE]: eve$$restore_position (saved_mark); endon_error; saved_mark := mark (FREE_CURSOR); position (TEXT); ! snap cursor to text if get_info (eve$x_found_range, "type") = RANGE then if get_info (eve$x_found_range, "buffer") = current_buffer then on_range := TRUE; endif; endif; if on_range then if get_info (saved_mark, "within_range", eve$x_found_range) then if the_direction = FORWARD then position (end_of (eve$x_found_range)); move_horizontal (1); else position (beginning_of (eve$x_found_range)); if mark (NONE) <> beginning_of (current_buffer) then move_horizontal (-1); endif; endif; endif; else if the_direction = FORWARD then if mark (FREE_CURSOR) <> end_of (current_buffer) then if not replacing then move_horizontal (1); endif; endif; else if mark (FREE_CURSOR) <> beginning_of (current_buffer) then move_horizontal (-1); endif; endif; endif; loop !+ !KHF ! The following loop has been added to skip over ranges that have been !KHF ! set invisible and unmodifiable by Khf$Find_All. This could have side- !KHF ! effects if other packages set RECORD_ATTRIBUTE's to MODIFIABLE, OFF for !KHF ! user buffers. The "search_quietly" line is unmodified; the others are !KHF ! all new... !KHF !- !KHF Loop !KHF the_range := search_quietly (the_target, the_direction, exactness); !KHF Exitif the_range = 0; !KHF If Get_Info (the_range, "unmodifiable_records") !KHF Then !KHF If the_direction = FORWARD !KHF Then !KHF Position (End_of (the_range)); !KHF Move_horizontal (1); !KHF Else !KHF Position (the_range); !KHF If Mark (NONE) <> Beginning_of (CURRENT_BUFFER) !KHF Then !KHF Move_Horizontal (-1); !KHF Endif; !KHF Endif; !KHF Else !KHF Exitif 1; !KHF Endif; !KHF Endloop; !KHF exitif the_range = 0; if leading_whitespace then position (the_range); exitif current_offset = 0; move_horizontal (-1); if index (eve$x_whitespace, current_character) <> 0 then position (search_quietly (notany (eve$x_whitespace) | line_begin, reverse, exact)); if index (eve$x_whitespace, current_character) = 0 then move_horizontal (1); ! move back, not a whitespace char endif; the_range := create_range (mark (NONE), end_of (the_range), NONE); exitif; else move_horizontal (1); ! move back exitif; ! not whitespace char endif; else exitif 1; endif; endloop; if the_range <> 0 then eve$$x_saved_found_range := the_range; endif; position (saved_mark); return (the_range); endprocedure; ! eve$search ! EVE$CORE.TPU Page 65 procedure eve_reset ! RESET command on_error [OTHERWISE]: endon_error; if current_window = eve$prompt_window then return (FALSE); ! no learn_abort here endif; eve$unmap_if_mapped (eve$choice_window); if (eve$x_select_position <> 0) or ! Cancel SELECT (eve$x_box_array <> 0) then eve$clear_select_position; eve$message (EVE$_SELCAN); endif; eve$$remove_found_range; ! Cancel the found range eve$x_old_find_direction := FORWARD; ! Set FIND NEXT direction if current_window <> eve$command_window then set (FORWARD, current_buffer); ! Set direction FORWARD eve$update_status_lines; else eve$delete_start_line; ! cancel any incomplete command line eve$$exit_command_window; endif; eve$check_bad_window; eve$$release_scratch_buffer; ! unconditional release ! Clear the secondary select range in case there was an error between ! us and another DECwindows application. eve$clear_secondary_select; Khf$Find_All_Fin; ! Clear [WILDCARD] FIND ALL !KHF ! ranges and show all lines. !KHF return (TRUE); endprocedure; ! eve_reset ! EVE$EDIT.TPU Page 12 procedure eve_move_by_word ! Move to start of next/prev word ! Move to start of next/previous word, depending on current direction. ! Newlines act like words. local saved_mark; on_error [TPU$_CONTROLC]: eve$$restore_position (saved_mark); ! restore free cursor position eve$learn_abort; abort; [OTHERWISE]: eve$$restore_position (saved_mark); endon_error; if not eve$declare_intention (eve$k_action_short_move) then return (FALSE); endif; saved_mark := mark (FREE_CURSOR); if not get_info (current_window, "bound") then if get_info (current_window, "beyond_eob") then position (TEXT); ! snap to text return (TRUE); else if get_info (current_window, "before_bol") then position (TEXT); ! snap to text at left margin if current_direction = REVERSE then move_horizontal (-1); ! force error if at BOB !+ !KHF ! The move_horizontal has wrapped back to the previous line. Check !KHF ! whether it is an invisible line, and if so, use cursor_vertical to !KHF ! move to a visible one. Then make sure we position to the end of line !KHF ! on the new line. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Position (LINE_END); !KHF Endif; !KHF endif; return (TRUE); else position (TEXT); ! snap to text at EOL or middle of tab endif; endif; endif; if current_direction = REVERSE then if eve$in_prompt then if current_buffer = eve$help_prompt_buffer then ! eve$prompt_buffer should always have dir = FORWARD return (TRUE); endif; position (LINE_BEGIN); endif; if mark (NONE) = beginning_of (current_buffer) then move_vertical (-1); ! force error return endif; if (eve$start_of_word = 0) and (mark (FREE_CURSOR) <> beginning_of (current_buffer)) then move_horizontal (-1); !+ !KHF ! Check if we've wrapped back to the end of the previous line (current !KHF ! character null). If so, check whether it's an invisible line, and if !KHF ! so, cursor_vertical to a visble one, then move to the end of line. !KHF !- !KHF If CURRENT_CHARACTER = '' !KHF Then !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Position (LINE_END); !KHF Endif; !KHF Endif; endif; else if mark (NONE) = end_of (current_buffer) then move_vertical (1); ! force error return endif; if (eve$end_of_word = 0) then move_horizontal (1); !+ !KHF ! Check if we've wrapped forward to the next line (current offset zero). !KHF ! If so, check whether it's an invisible line, and if so, cursor_vertical !KHF ! to a visble one, then move to the beginning of line. !KHF !- !KHF If CURRENT_OFFSET = 0 !KHF Then !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (0); !KHF Position (LINE_BEGIN); !KHF Endif; !KHF Endif; !KHF endif; endif; return (TRUE); endprocedure; ! eve_move_by_word ! EVE$EDIT.TPU Page 42 procedure eve_move_by_line ! Move to start of line ! 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. ! ! Note that at the end of the command prompt in reverse, the cursor moves ! to the end of the previous line, not to the end of the prompt in the ! previous line - because the post command filter always leaves the cursor at ! the end of a command line if you've moved up or down in the command buffer. local cursor_is_free, ! True if cursor beyond end of current line saved_mark; on_error [TPU$_CONTROLC]: eve$$restore_position (saved_mark); eve$learn_abort; abort; [TPU$_BEGOFBUF, TPU$_ENDOFBUF]: eve$$restore_position (saved_mark); [OTHERWISE]: eve$$restore_position (saved_mark); endon_error; if not eve$declare_intention (eve$k_action_short_move) then return (FALSE); endif; cursor_is_free := not (get_info (current_buffer, "bound")); saved_mark := mark (FREE_CURSOR); position (TEXT); ! snap cursor to text if current_direction = REVERSE then ! In prompting window, go to previous line if within prompt if eve$in_prompting_window then if eve$in_prompt then move_vertical (-1); endif; ! NOTE: the command post filter always moves to the end of a new line ! in the command window. position (LINE_BEGIN); else ! not command if not cursor_is_free then if current_offset = 0 then move_vertical (-1); endif; endif; !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a visible line. Use Khf$$Invisible_Line to check, it avoids creating !KHF ! a mark if possible. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Endif; !KHF position (LINE_BEGIN); endif; else if cursor_is_free then position (saved_mark); if get_info (current_window, "beyond_eol") then position (LINE_END); ! Prevent padding. move_horizontal (1); ! Faster than move_vertical, & move_vert endif; ! doesn't always go to eol if else ! EDT-style column_move_vertical is ON if mark (NONE) <> end_of (current_buffer) then if current_character = "" ! on eol then move_horizontal (1); ! Faster than move_vertical + move_vert endif; ! doesn't always to to eol endif; endif; !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a mark if possible. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (0); !KHF Endif; !KHF position (LINE_END); ! gotta do this for all cases endif; return (TRUE); endprocedure; ! eve_move_by_line ! EVE$EDIT.TPU Page 43 procedure eve_move_down ! Move down one row (free and bound cursor) ! Move down one row, staying in the same column. Scroll if necessary. on_error [OTHERWISE]: endon_error; ! scroll the VT100 choice window if it's mapped if eve$$x_state_array {eve$$k_ambiguous_parse} then if (current_window = eve$command_window) and eve$on_a_pre_lk201 then eve$move_by_screen (1); return (TRUE); endif; endif; if not eve$declare_intention (eve$k_action_down_right) then return (FALSE); endif; if eve$x_bound_cursor then move_vertical (1); ! command post filter cleans up after this move_vertical !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a visible line. Use Khf$$Invisible_Line to check, it avoids creating !KHF ! a mark if possible. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical(0); !KHF Position (TEXT); !KHF Endif; !KHF else case cursor_vertical (1) from - 1 to 0 [-1]: cursor_vertical (-1); if scroll (current_window, 1) = 0 then eve$learn_abort; return FALSE; endif; [0]: if scroll (current_window, 1) = 0 then eve$learn_abort; return FALSE; endif; endcase; endif; return (TRUE); endprocedure; ! eve_move_down ! EVE$EDIT.TPU Page 44 procedure eve_move_left ! Move left one column (free and bound cursor) ! Move left one column. Do not wrap at edge of the screen. Local eol; ! Flag current position is at end of line !KHF on_error [OTHERWISE]: endon_error; if not eve$declare_intention (eve$k_action_up_left) then return (FALSE); endif; if eve$x_bound_cursor then move_horizontal (-1); !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a visible line. Use Khf$$Invisible_Line to check, it avoids creating !KHF ! a mark if possible. If the move_horizontal has wrapped to a new line, !KHF ! make sure we position to the LINE_END after the cursor_vertical. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF eol := (CURRENT_CHARACTER = ""); ! At LINE_END !KHF Cursor_Vertical(-1); !KHF Position (TEXT); !KHF If eol !KHF Then !KHF Position (LINE_END); !KHF Endif; !KHF Endif; !KHF else if cursor_horizontal (-1) = 0 then eve$learn_abort; return FALSE; endif; endif; return (TRUE); endprocedure; ! eve_move_left ! EVE$EDIT.TPU Page 45 procedure eve_move_right ! Move right one column (free and bound cursor) ! Move right one column. Do not wrap at edge of the screen. Local bol; ! Flag current position is at beginning of line !KHF on_error [OTHERWISE]: endon_error; if eve$in_prompting_window then if current_character = "" then return (TRUE); endif; endif; if not eve$declare_intention (eve$k_action_down_right) then return (FALSE); endif; if eve$x_bound_cursor then move_horizontal (1); !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a visible line. Use Khf$$Invisible_Line to check, it avoids creating !KHF ! a mark if possible. If the move_horizontal has wrapped to a new line, !KHF ! make sure we position to LINE_BEGIN after the cursor_vertical. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF bol := (CURRENT_OFFSET = 0); ! At LINE_BEGIN !KHF Cursor_Vertical(0); !KHF Position (TEXT); !KHF If bol !KHF Then !KHF Position (LINE_BEGIN); !KHF Endif; !KHF Endif; !KHF else if cursor_horizontal (1) = 0 then eve$learn_abort; return (FALSE); endif; endif; return (TRUE); endprocedure; ! eve_move_right ! EVE$EDIT.TPU Page 46 procedure eve_move_up ! Move up one row (free and bound cursor) ! Move up one row, staying in the same column. Scroll if necessary. on_error [OTHERWISE]: endon_error; ! scroll the VT100 choice window if it's mapped if eve$$x_state_array {eve$$k_ambiguous_parse} then if (current_window = eve$command_window) and eve$on_a_pre_lk201 then eve$move_by_screen (-1); return (TRUE); endif; endif; if not eve$declare_intention (eve$k_action_up_left) then return (FALSE); endif; if eve$x_bound_cursor then move_vertical (-1); !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a visible line. Use Khf$$Invisible_Line to check, it avoids creating !KHF ! a mark if possible. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical(-1); !KHF Position (TEXT); !KHF Endif; !KHF else case cursor_vertical (-1) [-1]: cursor_vertical (1); if scroll (current_window, -1) = 0 then eve$learn_abort; return FALSE; endif; [0]: if scroll (current_window, -1) = 0 then eve$learn_abort; return FALSE; endif; endcase; endif; return (TRUE); endprocedure; ! eve_move_up ! EVE$EDIT.TPU Page 48 procedure eve_top ! TOP ! Go to beginning of the current buffer on_error [OTHERWISE]: endon_error; if not eve$declare_intention (eve$k_action_up_left) then return (FALSE); endif; position (TEXT); ! snap cursor to text if mark (NONE) = beginning_of (current_buffer) then eve$message (EVE$_ATTOP); ! no learn_abort here else position (beginning_of (current_buffer)); !+ !KHF ! Due to a side effect of FIND ALL, we need to make sure we position to !KHF ! a visible line. Use Khf$$Invisible_Line to check, it avoids creating !KHF ! a mark if possible. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (0); !KHF Endif; !KHF endif; return (TRUE); endprocedure; ! eve_top ! eve$windows.tpu page 46 procedure eve$move_by_screen ! next/prev screen subprocedure (how_many_screens) ! number of screens to move - input ! 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. local how_much_scroll, ! how many lines to scroll scroll_window, ! window to be scrolled saved_window, ! current window saved_window_mark, ! current window's position saved_mark, ! position to move from (may be choices/cmd) this_column, ! column were in now this_row, ! current row in scroll_window new_top, ! temporary top scroll margin new_bottom, ! temporary bottom scroll margin saved_scrolls, ! boolean set if saved_scroll_xxx are valid saved_scroll_top, ! original value of scroll_top saved_scroll_bottom, ! original value of scroll_bottom saved_scroll_amount, ! original value of scroll_amount hiding_lines, ! Flags hidden lines from FIND ALL !KHF did_scroll; ! Actual number of lines scrolled !KHF on_error [tpu$_controlc]: eve$$restore_position (scroll_window); if (get_info (saved_mark, "type") = marker) and (not eve$x_bound_cursor) then ! restore the cursor position when free cursoring position (line_begin); ! snap cursor to column 1 if mark (none) = end_of (current_buffer) then cursor_horizontal (get_info (saved_mark, "offset_column") - 1); else cursor_horizontal (get_info (saved_mark, "offset_column") - get_info (mark (free_cursor), "offset_column")); endif; endif; if saved_scrolls then set (scrolling, scroll_window, eve$x_scrolling, saved_scroll_top, saved_scroll_bottom, saved_scroll_amount); update (scroll_window); endif; if saved_window <> scroll_window then eve$$restore_position (saved_window, saved_window_mark); endif; eve$learn_abort; abort; [tpu$_begofbuf, tpu$_endofbuf]: ! ignore beyond buffer errors, move to eve$move_by_screen := false; ! boundary and continue. [otherwise]: eve$$restore_position (scroll_window); if (get_info (saved_mark, "type") = marker) and (not eve$x_bound_cursor) then ! restore the cursor position when free cursoring position (line_begin); ! snap cursor to column 1 if mark (none) = end_of (current_buffer) then cursor_horizontal (get_info (saved_mark, "offset_column") - 1); else cursor_horizontal (get_info (saved_mark, "offset_column") - get_info (mark (free_cursor), "offset_column")); endif; endif; if saved_scrolls then set (scrolling, scroll_window, eve$x_scrolling, saved_scroll_top, saved_scroll_bottom, saved_scroll_amount); update (scroll_window); endif; if saved_window <> scroll_window then eve$$restore_position (saved_window, saved_window_mark); endif; endon_error; saved_window := current_window; saved_window_mark := mark (free_cursor); eve$move_by_screen := true; if saved_window = eve$command_window then if eve$$x_state_array {eve$$k_ambiguous_parse} then scroll_window := eve$choice_window; else scroll_window := eve$$x_pre_command_window; endif; position (scroll_window); else scroll_window := saved_window; endif; saved_mark := mark (free_cursor); this_column := get_info (saved_mark, "offset_column"); position (line_begin); ! snap cursor to column 1 how_much_scroll := get_info (scroll_window, "visible_length"); !*** v2.0 compat ! provide an overlap of so some old text remains in the window if get_info (scroll_window, "status_line") <> "" 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; if eve$x_units = coordinates then how_much_scroll := how_much_scroll * get_info (characters, "height"); endif; ! move, keeping the cursor stationary and scrolling the text under the cursor ! (except when within scroll margin at either top or bottom of buffer, in ! which case the cursor will have to move to the scroll margin after movement). ! 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, "current_row"); if this_row = 0 then ! screen info is not all updated yet this_row := get_info (scroll_window, "visible_top"); !*** v2.0 compat endif; saved_scroll_top := get_info (scroll_window, "scroll_top"); saved_scroll_bottom := get_info (scroll_window, "scroll_bottom"); saved_scroll_amount := get_info (scroll_window, "scroll_amount"); saved_scrolls := true; ! for error handler !+ !KHF ! Before going further, check whether there are any hidden lines in !KHF ! this buffer. If not, do the usual Set (SCROLLING) / Move_Vertical. !KHF ! If so, we'll use the SCROLL built-in, below. !KHF !- !KHF hiding_lines := khf$x_hiding_lines {CURRENT_BUFFER}; !KHF If hiding_lines = TPU$K_UNSPECIFIED !KHF Then !KHF hiding_lines := FALSE; !KHF Endif; !KHF !KHF !KHF If Not hiding_lines !KHF Then !KHF ! adjust temporary scroll margins to preclude screen manager adjusting for ! scroll margins (when cursor is at top or bottom of buffer) new_top := this_row - get_info (scroll_window, "visible_top"); !*** v2.0 compat new_bottom := get_info (scroll_window, "visible_bottom") - this_row; !*** v2.0 compat if how_many_screens >= 0 then if new_top < saved_scroll_top then new_top := saved_scroll_top; new_bottom := new_bottom - new_top; endif; else if new_bottom < saved_scroll_bottom then new_bottom := saved_scroll_bottom; new_top := new_top - new_bottom; endif; endif; set (scrolling, scroll_window, eve$x_scrolling, new_top, new_bottom, 0); move_vertical (how_many_screens * how_much_scroll); ! move Else !KHF how_much_scroll := (how_many_screens * how_much_scroll); !KHF did_scroll := Scroll (CURRENT_WINDOW, how_much_scroll); !KHF !KHF !+ !KHF ! There appears to be a bug in the SCROLL built-in. The valued returned !KHF ! is _supposed_ to be the signed number of lines the window actually !KHF ! scrolled, but instead, the value returned is always _non-negative_. !KHF ! We fix this in the if-block below. !KHF !- !KHF If how_much_scroll < 0 !KHF Then !KHF If did_scroll > 0 ! Looks like a BUG to me!!! !KHF Then !KHF did_scroll := -did_scroll; !KHF Endif; !KHF Endif; !KHF !KHF If did_scroll <> how_much_scroll !KHF Then !KHF Cursor_Vertical (how_much_scroll - did_scroll); !KHF Endif; !KHF If Get_Info (Mark(FREE_CURSOR), "beyond_eob") !KHF Then !KHF Position (TEXT); !KHF Endif; !KHF Endif; !KHF if not eve$x_bound_cursor then ! restore the cursor position when free cursoring if mark (none) = end_of (current_buffer) then cursor_horizontal (this_column - 1); else cursor_horizontal (this_column - get_info (mark (free_cursor), "offset_column")); endif; endif; ! *** someday we should not have to force a screen update *** update (scroll_window); set (scrolling, scroll_window, eve$x_scrolling, saved_scroll_top, saved_scroll_bottom, saved_scroll_amount); if saved_window <> scroll_window then eve$$restore_position (saved_window, saved_window_mark); endif; endprocedure; ! eve$move_by_screen !------------------------Modified EVE$EDT Procedures------------------------- ! EVE$EDT.TPU Page 7 procedure eve$edt_backspace ! Backspace !+ ! EDT -- Backspace ! Set cursor to beginning of line !- on_error [OTHERWISE]: endon_error; if not eve$declare_intention (eve$k_action_up_left) then return (FALSE); endif; if not (get_info (current_buffer, "bound")) then position (LINE_BEGIN); else if current_offset = 0 then move_vertical (-1); ! Output error message if @ bob !+ !KHF ! We've wrapped back to a new line. It's possible that this line is !KHF ! invisible. Use Khf$$Invisible_Line to check, it avoids creating a mark !KHF ! if possible. If we have, use cursor_vertical to move to a visible line !KHF ! if needed. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Position (TEXT); !KHF Endif; !KHF endif; position (LINE_BEGIN); ! Make sure we are at 0 endif; return (TRUE); endprocedure; ! eve$edt_backspace ! EVE$EDT.TPU Page 13 procedure eve$edt_eol ! Move to end of line !+ ! EDT -- Move to the next End of Line !- local saved_mark; on_error [TPU$_CONTROLC]: eve$$restore_position (saved_mark); ! restore free cursor position eve$learn_abort; abort; [OTHERWISE]: eve$$restore_position (saved_mark); endon_error; if not eve$declare_intention (eve$k_action_short_move) then return (FALSE); endif; saved_mark := mark (FREE_CURSOR); ! for errors position (TEXT); ! snap cursor to text if (current_window = eve$prompt_window) and (mark (NONE) <> end_of (current_buffer)) then if (length (current_line) = eve$x_prompt_length) then return (TRUE); endif; endif; if current_direction = FORWARD then if mark (NONE) <> end_of (current_buffer) then if eve$on_end_of_line then move_horizontal (1); !+ !KHF ! We've wrapped forward to a new line. It's possible that this line is !KHF ! invisible. Use Khf$$Invisible_Line to check, it avoids creating a mark !KHF ! if possible. If we have, use cursor_vertical to move to a visible line !KHF ! if needed. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (0); !KHF Position (TEXT); !KHF Endif; !KHF endif; position (LINE_END); else move_vertical (1); ! force an error msg at EOB endif; else if mark (NONE) = beginning_of (current_buffer) then position (saved_mark); move_vertical (-1); ! for error message endif; position (LINE_BEGIN); move_horizontal (-1); !+ !KHF ! As above, if necessary, move to the end of line on a visible line. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Position (LINE_END); !KHF Endif; !KHF endif; return (TRUE); endprocedure; ! eve$edt_eol ! EVE$EDT.TPU Page 14 procedure eve$edt_char ! Character !+ ! EDT -- Move one character in current direction !- local saved_mark; on_error [TPU$_CONTROLC]: eve$$restore_position (saved_mark); eve$learn_abort; abort; [OTHERWISE]: eve$$restore_position (saved_mark); endon_error; if not eve$declare_intention (eve$k_action_short_move) then return (FALSE); endif; saved_mark := mark (FREE_CURSOR); ! for errors if not get_info (current_window, "bound") then if get_info (current_window, "beyond_eob") then position (TEXT); ! snap to text return (TRUE); else if get_info (current_window, "before_bol") then position (TEXT); ! snap to text at left margin if current_direction = REVERSE then move_horizontal (-1); ! force error if at BOB !+ !KHF ! We've wrapped back to the previous line. It's possible that this line !KHF ! is invisible. Use Khf$$Invisible_Line to check, it avoids creating a !KHF ! mark if possible. If we have, use cursor_vertical to move to a visible !KHF ! line if needed. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Position (LINE_END); !KHF Endif; !KHF endif; return (TRUE); else if get_info (current_window, "middle_of_tab") then position (TEXT); ! snap to text (left of tab) if current_direction = FORWARD then move_horizontal (1); ! move right over tab endif; return (TRUE); else ! beyond_eol position (TEXT); ! snap to text at EOL endif; endif; endif; endif; if current_direction = FORWARD then move_horizontal (1); !+ !KHF ! Check CURRENT_OFFSET to see if we've wrapped to a new line. If so, use !KHF ! Khf$$Invisible_Line to see if we've hit an invisible line. If we have, !KHF ! use cursor_vertical to move to a visible one and position to the !KHF ! beginning of line. !KHF !- !KHF If (CURRENT_OFFSET = 0) And !KHF Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (0); !KHF Position (LINE_BEGIN); !KHF Endif; !KHF else move_horizontal (-1); !+ !KHF ! Check whether CURRENT_CHARACTER is null, indicating we've wrapped !KHF ! back to the previous line's eol. As above, if necessary, move to !KHF ! the end of line on a visible line. !KHF !- !KHF If (CURRENT_CHARACTER = "") And !KHF Khf$$Invisible_Line !KHF Then !KHF Cursor_Vertical (-1); !KHF Position (LINE_END); !KHF Endif; !KHF endif; return (TRUE); endprocedure; ! eve$edt_char ! EVE$EDT.TPU Page 15 procedure eve$edt_line ! Line !+ ! EDT -- Line !- local saved_mark; on_error [TPU$_CONTROLC]: eve$$restore_position (saved_mark); eve$learn_abort; abort; [OTHERWISE]: eve$$restore_position (saved_mark); endon_error; if not eve$declare_intention (eve$k_action_short_move) then return (FALSE); endif; saved_mark := mark (FREE_CURSOR); ! for errors position (TEXT); ! snap cursor to text if current_window = eve$prompt_window then return (TRUE); endif; ! get to start of next/prev line if current_direction = FORWARD then position (LINE_END); move_horizontal (1); else if current_offset = 0 then move_horizontal (-1); else if (current_window = eve$command_window) and (current_offset = eve$x_command_prompt_length) then position (LINE_BEGIN); move_horizontal (-1); endif; endif; position (LINE_BEGIN); endif; ! NOTE: in REVERSE at the end of the prompt in the command window, the ! following 4 lines of code are negated by the command post filter ! which always moves to the end of a new line in the command window. if current_window = eve$command_window then move_horizontal (eve$x_command_prompt_length); endif; !+ !KHF ! Make sure the current position is on a visible line. If not, use !KHF ! cursor_vertical to position to a visible one. !KHF !- !KHF If Khf$$Invisible_Line !KHF Then !KHF If CURRENT_DIRECTION = FORWARD !KHF Then !KHF Cursor_Vertical (0); !KHF Else !KHF Cursor_Vertical (-1); !KHF Endif; !KHF Position (LINE_BEGIN); !KHF Endif; !KHF return (TRUE); endprocedure; ! eve$edt_line ! EVE$EDT.TPU Page 23 procedure eve$edt_section ! Scroll screen (direction_to_go) !+ ! EDT Section Key Emulation, use scroll regions set by SET SCROLL MARGINS cmd. !- local how_much_scroll, ! How many lines to scroll visible_length, ! Length of text in window scroll_window, ! Window to be scrolled this_row, saved_window, saved_window_mark, saved_mark, this_column, hiding_lines, ! Flag hidden lines from FIND ALL !KHF did_scroll; ! Actual number of lines scrolled !KHF on_error [TPU$_CONTROLC]: eve$$restore_position (scroll_window); if (get_info (saved_mark, "type") = MARKER) and (not eve$x_bound_cursor) then ! restore the cursor position when free cursoring position (LINE_BEGIN); ! snap cursor to column 1 if mark (NONE) = end_of (current_buffer) then cursor_horizontal (get_info (saved_mark, "offset_column") - 1); else cursor_horizontal (get_info (saved_mark, "offset_column") - get_info (mark (FREE_CURSOR), "offset_column")); endif; endif; if saved_window <> scroll_window then eve$$restore_position (saved_window, saved_window_mark); endif; eve$learn_abort; abort; [OTHERWISE]: eve$$restore_position (scroll_window); if (get_info (saved_mark, "type") = MARKER) and (not eve$x_bound_cursor) then ! restore the cursor position when free cursoring position (LINE_BEGIN); ! snap cursor to column 1 if mark (NONE) = end_of (current_buffer) then cursor_horizontal (get_info (saved_mark, "offset_column") - 1); else cursor_horizontal (get_info (saved_mark, "offset_column") - get_info (mark (FREE_CURSOR), "offset_column")); endif; endif; if saved_window <> scroll_window then eve$$restore_position (saved_window, saved_window_mark); endif; endon_error; saved_window := current_window; saved_window_mark := mark (FREE_CURSOR); if saved_window = eve$command_window then ! scroll the choice window if it's mapped if eve$$x_state_array {eve$$k_ambiguous_parse} then if direction_to_go = FORWARD ! Insure the choices buffer scrolls with then ! each next/prev screen key press. return (eve$move_by_screen (1)); else return (eve$move_by_screen (-1)); endif; else ! else scroll text window (not command window) scroll_window := eve$$x_pre_command_window; endif; position (scroll_window); else scroll_window := saved_window; endif; saved_mark := mark (FREE_CURSOR); this_column := get_info (saved_mark, "offset_column"); position (LINE_BEGIN); ! snap cursor to column 1 visible_length := (get_info (scroll_window, "visible_length") - (get_info (scroll_window, "status_line") <> "")); ! the default scroll_percent = 75% how_much_scroll := (visible_length * eve$x_scroll_percent) / 100; if how_much_scroll = 0 then how_much_scroll := 1; endif; if eve$x_units = COORDINATES then how_much_scroll := how_much_scroll * get_info (CHARACTERS, "height"); endif; if direction_to_go = REVERSE then how_much_scroll := -how_much_scroll; endif; this_row := get_info (scroll_window, "current_row"); if this_row = 0 then ! update will put it in row 1 later this_row := get_info (scroll_window, "visible_top"); endif; !+ !KHF ! Before going further, check whether there are any hidden lines in !KHF ! this buffer. If not, do the usual Set (SCROLLING) / Move_Vertical. !KHF ! If so, we'll use the SCROLL built-in below. !KHF !- !KHF hiding_lines := khf$x_hiding_lines {CURRENT_BUFFER}; !KHF If hiding_lines = TPU$K_UNSPECIFIED !KHF Then !KHF hiding_lines := FALSE; !KHF Endif; !KHF !KHF !KHF If Not hiding_lines !KHF Then !KHF move_vertical (how_much_scroll); ! "SCROLL" Else !KHF did_scroll := Scroll (CURRENT_WINDOW, how_much_scroll); !KHF !KHF !+ !KHF ! There appears to be a bug in the SCROLL built-in. The valued returned !KHF ! is _supposed_ to be the signed number of lines the window actually !KHF ! scrolled, but instead, the value returned is always _non-negative_. !KHF ! We fix this in the if-block below. !KHF !- !KHF If how_much_scroll < 0 !KHF Then !KHF If did_scroll > 0 ! Looks like a BUG to me!!! !KHF Then !KHF did_scroll := -did_scroll; !KHF Endif; !KHF Endif; !KHF !KHF If did_scroll <> how_much_scroll !KHF Then !KHF Cursor_Vertical (how_much_scroll - did_scroll); !KHF Endif; !KHF If Get_Info (Mark(FREE_CURSOR), "beyond_eob") !KHF Then !KHF Position (TEXT); !KHF Endif; !KHF Endif; !KHF if not eve$x_bound_cursor then ! restore the cursor position when free cursoring if mark (NONE) = end_of (current_buffer) then cursor_horizontal (this_column - 1); else cursor_horizontal (this_column - get_info (mark (FREE_CURSOR), "offset_column")); endif; endif; if saved_window <> scroll_window then eve$$restore_position (saved_window, saved_window_mark); endif; return (TRUE); endprocedure; ! eve$edt_section