! ABEL_CUTPAS.TPU ! ! Table of Contents as of 27-Mar-1988 ! ! Procedure name Page Description ! -------------- ---- ----------- ! ! eve_select 1 Revised select command ! eve_remove 2 Revised remove command ! eve_insert_here 3 Revised insert_here command ! eve_block_select 4 Start a block function ! eve_block_remove 5 Block remove ! eve_block_insert_here 6 Block insert ! eve_block_text 7 Put a block of text ! Page 1 procedure eve_select ! Revised select command ! Start or cancel a select range. When user selects a range, give a mark ! called "select" that can be used to get back here. This mark remembers the ! last used select position; it is not guaranteed since the user can change the ! mark on his own, and it is not erased once the select is cancelled or ! finished. ! ! Qualifiers: ! /select boolean start a select no matter what previous state ! /reset boolean cancel a select no matter what previous state ! (has priority over /select) ! ! Globals: ! eve$x_select_position mark position of select ! eve$mark_select mark position of select for "go to" command ! ! Source: ! Eve if abl$q_select then eve$x_select_position := 0; endif; if (abl$q_reset) or (eve$x_select_position <> 0) then eve$x_select_position := 0; message ("Selection cancelled"); return else eve$x_select_position := select (eve$x_highlighting); message ("Selection started...remove when finished"); ! ! Give the user a mark for free that s/he can use to get back here ! eve$mark_select := mark(none); endif; endprocedure ! Page 2 procedure eve_remove ! Revised remove command ! Move the select region to the insert here buffer. ! ! To figure out what's going on with the paste buffer, you have to know how ! DEC stored text in there. Moving text into a completely empty buffer gives ! a free split_line (try inserting text before the [End of buffer] marker), but ! that can get confusing when doing a paste (did the last split_line come from ! the user or for free?). DEC decided to always ignore the last split_line by ! always performing one during a cut and an append_line during a paste; the ! last split_line is never considered to be part of the cut text. ! ! To append, we move the cursor to the last character before the last ! split_line. Appending to a completely empty paste buffer doesn't make sense ! since there is no character before the final split_line, in fact there isn't ! even a final split_line. If the paste buffer is empty and the user wants an ! append, we do a regular cut instead and the user will never know. ! ! Qualifiers: ! /append boolean do not erase previous contents of paste buffer ! /remove boolean erase select region from original buffer ! /reset boolean reset select range when done ! ! Globals: ! eve$x_select_position mark position of select ! ! Source: ! Eve local this_position, ! Marker for current cursor position remove_range; ! Range being removed on_error endon_error; this_position := mark (none); if eve$x_select_position = 0 then message ("Use Select before using Remove"); return 0; endif; if get_info (eve$x_select_position, "buffer") <> current_buffer then message ("Remove must be used in the same buffer as Select"); return 0; endif; 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; ! ! Appending to an empty buffer is confusing...if paste emtpy, no append ! if get_info(paste_buffer,"record_count") = 0 then abl$q_append := 0 endif; ! ! Set up our position in the paste buffer ! if abl$q_append then ! ! If appending, go to the end of the last line ! position (end_of(paste_buffer)); move_vertical(-1); position(search(line_end,forward)); else ! ! If not appending, erase the buffer, open a line, place cursor at ! start of open line ! erase (paste_buffer); position (paste_buffer); split_line; move_vertical (-1); endif; if abl$q_remove then move_text(remove_range); else copy_text(remove_range); endif; position (this_position); if abl$q_reset then eve$x_select_position := 0; remove_range := 0; endif; message ("Remove completed"); endprocedure; ! Page 3 procedure eve_insert_here ! Revised insert_here command ! Eve's paste routine ! ! Source: ! Eve local this_mode; ! Keyword for current mode if eve$check_bad_window then message("Cannot use insert here on this window"); return 0 endif; if beginning_of (paste_buffer) <> end_of (paste_buffer) then this_mode := get_info (current_buffer, "mode"); set (insert, current_buffer); copy_text (paste_buffer); append_line; ! did a split_line during eve_remove (see doc in 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 4 procedure eve_block_select ! Start a block function ! Similar in concept to Eve's Select command, but marks a corner of a block. ! Give the user a mark that s/he can use with the "go to" command if they need ! to get back here again. This mark remembers the last used block select ! position; it is not guaranteed since the user can change the mark on his own, ! and it is not erased once the block select is cancelled or finished. ! ! Qualifiers: ! /select boolean start a select no matter what previous state ! /reset boolean cancel a select no matter what previous state ! (has priority over /select) ! ! Globals: ! abl$x_block_select_position mark position of block select ! eve$mark_block_select mark position of block select for use ! with "go to" command ! ! Source: ! Eva2 if abl$q_select then abl$x_block_select_position := 0; endif; if (abl$q_reset) or (abl$x_block_select_position <> 0) then abl$x_block_select_position := 0; message ("Block select cancelled"); return else ! ! Place a mark at current cursor position... ! if there isn't a character here, put one ! if get_info(current_buffer,"character") = "" then copy_text(" "); move_horizontal(-1) endif; abl$x_block_select_position := mark(reverse); message("Block selection started"); ! ! Give the user a mark for free that s/he can use to get back here ! eve$mark_block_select := mark(none); endif; endprocedure ! Page 5 procedure eve_block_remove ! Block remove ! Similar to Eve's Remove command for a block of text; Block Select is the ! other corner of the text; mode-sensitive ! ! Qualifiers: ! /append boolean do not erase previous contents of paste buffer ! /remove boolean erase block of text from original buffer ! /reset boolean reset block select range when done ! /log boolean give informational messages ! ! Globals: ! abl$x_block_select_position mark position of block select ! ! Source: ! Eva2 local orig_buffer, orig_mode, x1, y1, x2, y2, x_len, y_len, other_block_select_position, line, ob_line, pb_line; ! ! Handle error situations ! if get_info(get_info(current_buffer,"tab_stops"),"type") = string then message("Cannot perform block functions with irregularly spaced tabs"); return 0; endif; if abl$x_block_select_position = 0 then message("Use Block Select before using Block Remove"); return 0; endif; if get_info(mark(none),"buffer") <> get_info(abl$x_block_select_position,"buffer") then message("Block Select (buffer " + get_info(get_info(abl$x_block_select_position,"buffer"),"name") + ") and Block Remove must be in same buffer"); return 0; endif; ! ! Initializations ! orig_buffer:=current_buffer; orig_mode:=get_info(current_buffer,"mode"); set(insert,current_buffer); set(insert,paste_buffer); ! ! Get line and offset of both marks ! other_block_select_position:=mark(none); abl$notab_offset(x1); y1 := eve$what_line; position(abl$x_block_select_position); abl$notab_offset(x2); y2 := eve$what_line; ! ! Determine lengths of ranges, and make sure x1 has lower of x1 and x2 ! (x1 is not an offset, but character number in the line) ! x_len := abl$abs(x1 - x2) + 1; y_len := abl$abs(y1 - y2) + 1; if x1 > x2 then x1 := x2 endif; x1 := x1 + 1; ! ! Position and virtual mark the upper left position of the block ! if other_block_select_position < abl$x_block_select_position then position(other_block_select_position) endif; abl$notab_line(line); move_horizontal(-current_offset); erase_character(length(current_line)); copy_text(line); move_horizontal(-current_offset + x1 - 1); abl$virtual_mark; if not abl$q_append then erase(paste_buffer) endif; move_horizontal(-current_offset); loop exitif y_len = 0; abl$notab_line(line); ! ! Make the line to go into the paste buffer ! pb_line := substr(line,x1,x_len); position(end_of(paste_buffer)); copy_text(pb_line); position(orig_buffer); if abl$q_remove then ! ! Process the line for the original buffer ! ob_line := substr(line,1,x1 - 1); if orig_mode = overstrike then ob_line := ob_line + substr(eve$x_spaces,1,x_len); endif; ob_line := ob_line + substr(line,x1 + x_len,1000); move_horizontal(-current_offset); erase_character(length(current_line)); copy_text(ob_line); endif; ! ! Process the next line ! move_vertical(1); y_len := y_len - 1; endloop; move_vertical(-1); if abl$q_reset then abl$x_block_select_position := 0; endif; abl$virtual_position; set(orig_mode,current_buffer); if abl$q_log then message("Block Remove completed"); endif; endprocedure ! Page 6 procedure eve_block_insert_here ! Block insert ! Similar to Eve's Insert Here command for a block of text; mode-sensitive ! ! Qualifiers: ! /log boolean give informational messages ! ! Source: ! Eva2 local orig_buffer, orig_mode, first_paste_length, insert_offset, ob_line, pb_line; ! ! Handle error situations ! if get_info(get_info(current_buffer,"tab_stops"),"type") = string then message("Cannot perform block functions with irregularly spaced tabs"); return 0; endif; ! ! Initializations ! orig_buffer:=current_buffer; orig_mode:=get_info(current_buffer,"mode"); set(insert,current_buffer); abl$virtual_mark; abl$notab_offset(insert_offset); position(beginning_of(paste_buffer)); first_paste_length := length(current_line); loop exitif mark(none) = end_of(paste_buffer); pb_line := current_line; move_vertical(1); position(orig_buffer); if mark(none) <> end_of(orig_buffer) then abl$notab_line(ob_line) else ob_line := "" endif; if length(ob_line) < insert_offset then ob_line := ob_line + substr(eve$x_spaces,1,insert_offset) endif; if orig_mode = insert then ob_line := substr(ob_line,1,insert_offset) + pb_line + substr(ob_line,insert_offset + 1,1000); else ob_line := substr(ob_line,1,insert_offset) + pb_line + substr(ob_line,insert_offset + 1 + length(pb_line),1000); endif; if mark(none) <> end_of(orig_buffer) then move_horizontal(-current_offset); erase_character(length(current_line)); endif; copy_text(ob_line); move_vertical(1); position(paste_buffer); endloop; position(orig_buffer); abl$virtual_position; move_horizontal(first_paste_length); set(orig_mode,current_buffer); if abl$q_log then message("Block Insert Here completed"); endif; endprocedure ! Page 7 procedure eve_block_text($pb_line) ! Put a block of text ! Allows user to specify text to use for a block insert here ! ! Qualifiers: ! /check boolean make sure column for Block Select and our ! current column are same (Block Select column ! used if /NOCHECK) ! /reset boolean reset the block select when done ! /prompt boolean take input from user, else use paste buffer ! ! Globals: ! abl$x_block_select_position mark position of block select ! ! Source: ! Eva2 local orig_buffer, orig_mode, insert_offset, ob_line, pb_line, x1,x2,y1,y2,y_len; ! ! Handle error situations ! if get_info(get_info(current_buffer,"tab_stops"),"type") = string then message("Cannot perform block functions with irregularly spaced tabs"); return 0; endif; if (abl$x_block_select_position = 0) then message("Use Block Select before using Block Text"); return 0; endif; if get_info(mark(none),"buffer") <> get_info(abl$x_block_select_position,"buffer") then message("Block select (buffer " + get_info(get_info(abl$x_block_select_position,"buffer"),"name") + ") and Block Text must be in same buffer"); return 0; endif; ! ! Initializations ! orig_buffer:=current_buffer; if abl$q_prompt then if not eve$prompt_string($pb_line,pb_line,"Text to insert: ", "Aborted...") then return 0 endif; else position(beginning_of(paste_buffer)); pb_line := current_line; position(orig_buffer); if pb_line = "" then message("No string found in Insert Here buffer"); return 0; endif; endif; orig_mode:=get_info(current_buffer,"mode"); set(insert,current_buffer); ! ! Get line and offset of both marks ! other_block_select_position:=mark(none); abl$notab_offset(x1); y1 := eve$what_line; position(abl$x_block_select_position); abl$notab_offset(x2); y2 := eve$what_line; ! ! Leave position at the mark closer to beginning of buffer ! if y1 <= y2 then position(other_block_select_position) endif; ! ! Determine lengths of ranges ! if abl$q_check then if x1 <> x2 then message("Block Select (column " + str(x2+1) + ") and current column (column " + str(x1+1) + ") not the same; aborted"); return 0; endif; else message("Using column "+str(x2+1)+" specified in Block Select"); endif; y_len := abl$abs(y1 - y2) + 1; abl$virtual_mark; abl$notab_offset(insert_offset); loop exitif y_len = 0; if mark(none) <> end_of(orig_buffer) then abl$notab_line(ob_line) else ob_line := "" endif; if length(ob_line) < insert_offset then ob_line := ob_line + substr(eve$x_spaces,1,insert_offset) endif; if orig_mode = insert then ob_line := substr(ob_line,1,insert_offset) + pb_line + substr(ob_line,insert_offset + 1,1000); else ob_line := substr(ob_line,1,insert_offset) + pb_line + substr(ob_line,insert_offset + 1 + length(pb_line),1000); endif; if mark(none) <> end_of(orig_buffer) then move_horizontal(-current_offset); erase_character(length(current_line)); endif; copy_text(ob_line); move_vertical(1); y_len := y_len - 1; endloop; abl$virtual_position; move_horizontal(length(pb_line)); set(orig_mode,current_buffer); if abl$q_reset then abl$x_block_select_position := 0; endif; endprocedure