gregg@a.cs.okstate.edu@mandrill.CWRU.Edu (Gregg Wonderly) (10/13/87)
$ WRITE SYS$OUTPUT "Creating ""VI.4""" $ CREATE VI.4 $ DECK/DOLLARS=$$EOD$$ ! ! ! The VI EDITOR written in VAXTPU ! ! Written by Gregg Wonderly ! Mathematics Department ! Oklahoma State University ! Stillwater Oklahoma, 74078 ! ! internet: gregg@nemo.math.okstate.edu ! uucp: okstate!nemo.math.okstate.edu!gregg ! ! Version number 1, edit 482, 11-OCT-1987 13:55:35.87 ! ! This program is the property of the author, and you should refrain ! from trying to make a profit from it (that's not nice). ! ! You can pass it around freely, as you should have gotten it for free. ! All I ask is that you give credit where credit is due. ! ! ! ! Initialize TPU for VI emulation. ! PROCEDURE vi$init_vars LOCAL i; message_buffer := 0; message_window := 0; command_buffer := 0; command_window := 0; show_buffer := 0; info_window := 0; choice_buffer := 0; choice_window := 0; vi$last_mapped := 0; vi$last_insert := 0; vi$bracket_chars := "{}()[]"; ! The recognized brackets. ! interline movement that is backwards, or different than the others vi$abbr_ := ""; vi$back_moves := "bB0FT^("; vi$weird_moves := "ft$DeE%"; vi$weird2_moves := "h"; vi$dot_keys := "iIdpPDxXaAcCoOrRSs<>"; vi$_lower_chars := "abcdefghijklmnopqrstuvwxyz"; vi$_upper_chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; vi$_letter_chars := vi$_lower_chars + vi$_upper_chars; vi$_numeric_chars := "0123456789"; vi$_alpha_chars := vi$_letter_chars + "_" + vi$_numeric_chars; vi$_sym_chars := vi$_alpha_chars + "$"; vi$_ctl_chars := ""; i := 0; LOOP EXITIF (i = 32); vi$_ctl_chars := vi$_ctl_chars + ASCII (i); i := i + 1; ENDLOOP; vi$_space_chars := " " + vi$_ctl_chars; vi$_punct_chars := "!@`~#$%^&*()-=+{}[];:'""\|,.?/><"; vi$_ex_separs := ", "; vi$_ascii_chars := ""; vi$_ws := ",./?;:'""\|[]{}-=+)(*&^%$#@!~`" + vi$_space_chars; vi$no_space := " " + ASCII(9) + ASCII (10) + ASCII(11) + ASCII(13); i := 0; LOOP EXITIF (i = 256); vi$_ascii_chars := vi$_ascii_chars + ASCII (i); i := i + 1; ENDLOOP; vi$pch := " "; i := 32; LOOP EXITIF (i = 256); vi$pch := vi$pch + ASCII (i); i := i + 1; ENDLOOP; vi$m_level := 0; vi$in_learn := 0; vi$playing_back := 0; vi$dcl_buf := 0; vi$dcl_process := 0; vi$send_dcl := 1; vi$tag_buf := 0; vi$tag_files := "tags"; vi$tag_case := EXACT; vi$in_ws := 0; vi$in_global := 0; vi$in_occlusion := 0; vi$old_occ_win := 0; vi$occluding_win := 0; vi$error_bells := 1; vi$show_mode := 0; vi$tmp_key_buf := 0; vi$last_mess := ""; vi$max_offset := 0; vi$new_offset := 1; vi$old_place := 0; vi$select_pos := 0; vi$term_vt200 := 0; vi$scr_width := 0; vi$scr_length := 0; vi$next_blank := "" & LINE_BEGIN & LINE_END; vi$para_str := "P "; vi$para_pat := "" & LINE_BEGIN & (".P"); vi$sect_str := "CHHLPG+c"; vi$sect_pat := "" & LINE_BEGIN & (".CH"| ".HL"| ".PG"| "{"); vi$last_cmd := 0; vi$last_filter := 0; vi$replace_separ := 0; vi$replace_source := 0; vi$replace_dest := 0; VI$DELETE_TYPE := 1; VI$CHANGE_TYPE := 2; VI$OTHER_TYPE := 3; VI$YANK_TYPE := 4; VI$FILTER_TYPE := 5; VI$SHIFT_TYPE := 6; vi$command_type := VI$OTHER_TYPE; vi$cu_cwd := 1; vi$cu_trnlnm_job := 2; vi$cu_trnlnm_proc := 3; vi$cu_trnlnm_sys := 4; vi$cu_trnlnm_group := 5; vi$cu_getmsg := 6; vi$cu_set_sysdisk := 7; vi$cu_sleep := 8; vi$cu_pasthru_on := 9; vi$cu_pasthru_off := 10; vi$filter_proc := 0; vi$filter_buf := 0; vi$push_key_buf := 0; vi$ex_mode_buffer := 0; vi$global_var := 0; vi$macro_active := "$$active_macro$$"; vi$_find_pat := 0; vi$wrap_scan := 1; vi$last_key := 0; vi$last_keys := 0; vi$cur_keys := 0; vi$key_buf := 0; vi$min_update := 1; vi$tab_amount := 8; vi$shift_width := 4; vi$spaces := " "; vi$use_tabs := 1; vi$in_show_match := 0; vi$report := 5; vi$auto_write := 0; vi$ignore_case := EXACT; vi$wrap_margin := 0; vi$magic := 1; vi$undo_map := 1; vi$undo_line_str := 0; vi$undo_line_mark := 0; vi$undo_line := 0; vi$undo_offset := 0; vi$how_much_scroll := 12; vi$search_string := 0; vi$last_search_dir := 1; vi$undo_start := 0; vi$undo_end := 0; vi$undo_buffer := 0; vi$undo_valid := 0; VI$HERE := 0; VI$AFTER := 1; VI$LINE_MODE := 1; VI$IN_LINE_MODE := 2; vi$cur_level := 0; vi$global_mark := 0; vi$yank_mode := 0; vi$temp_buf := 0; vi$cur_text := ""; ! Where text to PUT comes from. ! The ten deletion buffers. vi$del_buf_1 := 0; vi$del_buf_2 := 0; vi$del_buf_3 := 0; vi$del_buf_4 := 0; vi$del_buf_5 := 0; vi$del_buf_6 := 0; vi$del_buf_7 := 0; vi$del_buf_8 := 0; vi$del_buf_9 := 0; ! Named buffers accessible from the keyboard characters. vi$ins_buf_a := 0; vi$ins_buf_b := 0; vi$ins_buf_c := 0; vi$ins_buf_d := 0; vi$ins_buf_e := 0; vi$ins_buf_f := 0; vi$ins_buf_g := 0; vi$ins_buf_h := 0; vi$ins_buf_i := 0; vi$ins_buf_j := 0; vi$ins_buf_k := 0; vi$ins_buf_l := 0; vi$ins_buf_m := 0; vi$ins_buf_n := 0; vi$ins_buf_o := 0; vi$ins_buf_p := 0; vi$ins_buf_q := 0; vi$ins_buf_r := 0; vi$ins_buf_s := 0; vi$ins_buf_t := 0; vi$ins_buf_u := 0; vi$ins_buf_v := 0; vi$ins_buf_w := 0; vi$ins_buf_x := 0; vi$ins_buf_y := 0; vi$ins_buf_z := 0; ! The 26 marks available vi$mark_a := 0; vi$mark_b := 0; vi$mark_c := 0; vi$mark_d := 0; vi$mark_e := 0; vi$mark_f := 0; vi$mark_g := 0; vi$mark_h := 0; vi$mark_i := 0; vi$mark_j := 0; vi$mark_k := 0; vi$mark_l := 0; vi$mark_m := 0; vi$mark_n := 0; vi$mark_o := 0; vi$mark_p := 0; vi$mark_q := 0; vi$mark_r := 0; vi$mark_s := 0; vi$mark_t := 0; vi$mark_u := 0; vi$mark_v := 0; vi$mark_w := 0; vi$mark_x := 0; vi$mark_y := 0; vi$mark_z := 0; vi$endpos := 0; vi$new_endpos := 0; vi$start_pos := 0; VI$ALPHA_TYPE := 1; VI$PUNCT_TYPE := 2; VI$SPACE_TYPE := 3; VI$EOL_TYPE := 4; vi$temp_buf_num := 1; vi$last_s_func := 0; vi$last_s_char := 0; vi$active_count := 0; vi$cmd_keys := "c_keys"; vi$move_keys := "m_keys"; vi$edit_keys := "e_keys"; ENDPROCEDURE; ! ! Map all of the key bindings into the proper key maps. ! ! The "c_keys" map is used for command mode key processing. ! The "e_keys" map is used during line editing. ! The "m_keys" map is used to determine movement associated with ! a particular key. ! PROCEDURE vi$init_keys ! Define all of the command mode keys. vi$cmd_keys := CREATE_KEY_MAP ("c_keys"); DEFINE_KEY ("vi$make_full_screen", KP0, "", vi$cmd_keys); DEFINE_KEY ("vi$delete_window", KP1, "", vi$cmd_keys); DEFINE_KEY ("vi$split_here", KP2, "", vi$cmd_keys); DEFINE_KEY ("vi$next_window", KP3, "", vi$cmd_keys); DEFINE_KEY ("vi$shrink_window(vi$cur_active_count)", KP4, "", vi$cmd_keys); DEFINE_KEY ("vi$enlarge_window(vi$cur_active_count)", KP5, "", vi$cmd_keys); DEFINE_KEY ("vi$previous_window", KP6, "", vi$cmd_keys); DEFINE_KEY ("vi$prev_screen", CTRL_B_KEY, "vi$prev_screen", vi$cmd_keys); DEFINE_KEY ("vi$screen_forward", CTRL_D_KEY, "vi$screen_forward", vi$cmd_keys); DEFINE_KEY ("vi$pull_push_line (1)", CTRL_E_KEY, "vi$pull_push_line (1)", vi$cmd_keys); DEFINE_KEY ("vi$next_screen", CTRL_F_KEY, "vi$next_screen", vi$cmd_keys); DEFINE_KEY ("vi$what_line", CTRL_G_KEY, "vi$what_line", vi$cmd_keys); DEFINE_KEY ("vi$move_left", CTRL_H_KEY, "vi$move_left", vi$cmd_keys); DEFINE_KEY ("refresh", CTRL_L_KEY, "refresh", vi$cmd_keys); DEFINE_KEY ("vi$_next_line", CTRL_N_KEY, "vi$_next_line", vi$cmd_keys); DEFINE_KEY ("vi$do_macro('k0', 0)", CTRL_P_KEY, "vi$do_macro('k0', 0)", vi$cmd_keys); DEFINE_KEY ("vi$remember", CTRL_R_KEY, "vi$remember", vi$cmd_keys); DEFINE_KEY ("vi$screen_backward", CTRL_U_KEY, "vi$screen_backward", vi$cmd_keys); DEFINE_KEY ("vi$send_to_dcl (CURRENT_LINE)", CTRL_X_KEY, "vi$send_to_dcl (CURRENT_LINE)", vi$cmd_keys); DEFINE_KEY ("vi$pull_push_line (-1)", CTRL_Y_KEY, "vi$pull_push_line (-1)", vi$cmd_keys); DEFINE_KEY ("vi$to_tag(0)", KEY_NAME(ASCII(29)), "vi$to_tag(0)", vi$cmd_keys); DEFINE_KEY ("vi$move_prev_buf", KEY_NAME(ASCII(30)), "vi$move_prev_buf", vi$cmd_keys); DEFINE_KEY ("vi$do_help('')", PF2, "vi$do_help('')", vi$cmd_keys); DEFINE_KEY ("vi$on_escape", PF1, "vi$on_escape", vi$cmd_keys); DEFINE_KEY ("vi$on_escape", F11, "vi$on_escape", vi$cmd_keys); DEFINE_KEY ("vi$_go_to_marker", KEY_NAME ("'"), "vi$_go_to_marker", vi$cmd_keys); DEFINE_KEY ("vi$_go_to_marker", KEY_NAME ("`"), "vi$_go_to_marker", vi$cmd_keys); DEFINE_KEY ("vi$select_buffer", KEY_NAME ('"'), "vi$select_buffer", vi$cmd_keys); DEFINE_KEY ("vi$_match_brackets", KEY_NAME ('%'), "vi$_match_brackets", vi$cmd_keys); DEFINE_KEY ("vi$_change_case", KEY_NAME ('~'), "vi$_change_case", vi$cmd_keys); DEFINE_KEY ("vi$region_left", KEY_NAME ('<'), "vi$region_left", vi$cmd_keys); DEFINE_KEY ("vi$region_right", KEY_NAME ('>'), "vi$region_right", vi$cmd_keys); DEFINE_KEY ("vi$_next_line", KEY_NAME ('+'), "vi$_next_line", vi$cmd_keys); DEFINE_KEY ("vi$do_macro('k^', 0)", KEY_NAME ('-'), "vi$do_macro('k^', 0)", vi$cmd_keys); DEFINE_KEY ("vi$_paragraph (-1)", KEY_NAME ('{'), "vi$_paragraph (-1)", vi$cmd_keys); DEFINE_KEY ("vi$_section (-1)", KEY_NAME ('['), "vi$_section (-1)", vi$cmd_keys); DEFINE_KEY ("vi$_begin_sentence", KEY_NAME ('('), "vi$_begin_sentence", vi$cmd_keys); DEFINE_KEY ("vi$_paragraph (1)", KEY_NAME ('}'), "vi$_paragraph (1)", vi$cmd_keys); DEFINE_KEY ("vi$_section (1)", KEY_NAME (']'), "vi$_section (1)", vi$cmd_keys); DEFINE_KEY ("vi$_end_sentence", KEY_NAME (')'), "vi$_end_sentence", vi$cmd_keys); DEFINE_KEY ("vi$insert_after", KEY_NAME ('a'), "vi$insert_after", vi$cmd_keys); DEFINE_KEY ("vi$do_macro('$a', 0)", KEY_NAME ('A'), "vi$do_macro('$a', 0)", vi$cmd_keys); DEFINE_KEY ("vi$_word_back", KEY_NAME ('b'), "vi$_word_back", vi$cmd_keys); DEFINE_KEY ("vi$_full_word_back", KEY_NAME ('B'), "vi$_full_word_back", vi$cmd_keys); DEFINE_KEY ("vi$_change", KEY_NAME ('c'), "vi$_change", vi$cmd_keys); DEFINE_KEY ("vi$do_macro ('c$', 0)", KEY_NAME ('C'), "vi$do_macro ('c$', 0)", vi$cmd_keys); DEFINE_KEY ("vi$_delete (0, -1)", KEY_NAME ('d'), "delete", vi$cmd_keys); DEFINE_KEY ("vi$_delete (KEY_NAME('$'), -1)", KEY_NAME ('D'), "delete_eol", vi$cmd_keys); DEFINE_KEY ("vi$_word_end", KEY_NAME ('e'), "vi$_word_end", vi$cmd_keys); DEFINE_KEY ("vi$_full_word_end", KEY_NAME ('E'), "vi$_full_word_end", vi$cmd_keys); DEFINE_KEY ("vi$_find_char (0)", KEY_NAME ('f'), "vi$_find_char (0)", vi$cmd_keys); DEFINE_KEY ("vi$_back_find_char (0)", KEY_NAME ('F'), "vi$_back_find_char (0)", vi$cmd_keys); DEFINE_KEY ("vi$go_to_line", KEY_NAME ('G'), "vi$go_to_line", vi$cmd_keys); DEFINE_KEY ("vi$move_left", KEY_NAME ('h'), "vi$move_left", vi$cmd_keys); DEFINE_KEY ("home", KEY_NAME ('H'), "home", vi$cmd_keys); DEFINE_KEY ("vi$insert_here", KEY_NAME ('i'), "vi$insert_here", vi$cmd_keys); DEFINE_KEY ("vi$insert_at_begin", KEY_NAME ('I'), "vi$insert_at_begin", vi$cmd_keys); DEFINE_KEY ("vi$move_down", KEY_NAME ('j'), "vi$move_down", vi$cmd_keys); DEFINE_KEY ("vi$_join_lines", KEY_NAME ('J'), "vi$_join_lines", vi$cmd_keys); DEFINE_KEY ("vi$move_up", KEY_NAME ('k'), "vi$move_up", vi$cmd_keys); DEFINE_KEY ("vi$move_right", KEY_NAME ('l'), "vi$move_right", vi$cmd_keys); DEFINE_KEY ("vi$last", KEY_NAME ('L'), "vi$last", vi$cmd_keys); DEFINE_KEY ("vi$_set_mark", KEY_NAME ('m'), "vi$_set_mark", vi$cmd_keys); DEFINE_KEY ("vi$middle", KEY_NAME ('M'), "vi$middle", vi$cmd_keys); DEFINE_KEY ("vi$_search_next(vi$last_search_dir)", KEY_NAME('n'), "vi$_search_next(vi$last_search_dir)", vi$cmd_keys); DEFINE_KEY ("vi$_search_next(-vi$last_search_dir)", KEY_NAME('N'), "vi$_search_next(-vi$last_search_dir)", vi$cmd_keys); DEFINE_KEY ("vi$open_below", KEY_NAME ('o'), "vi$open_below", vi$cmd_keys); DEFINE_KEY ("vi$open_here", KEY_NAME ('O'), "vi$open_here", vi$cmd_keys); DEFINE_KEY ("vi$put_here (VI$HERE, -1)", KEY_NAME ('P'), "vi$put_here (VI$HERE, -1)", vi$cmd_keys); DEFINE_KEY ("vi$put_after (-1)", KEY_NAME ('p'), "vi$put_after (-1)", vi$cmd_keys); DEFINE_KEY ("vi$_replace_char", KEY_NAME ('r'), "vi$_replace_char", vi$cmd_keys); DEFINE_KEY ("vi$_replace_str", KEY_NAME ('R'), "vi$_replace_str", vi$cmd_keys); DEFINE_KEY ("vi$do_macro('cl', 0)", KEY_NAME ('s'), "vi$do_macro('cl', 0)", vi$cmd_keys); DEFINE_KEY ("vi$_big_s", KEY_NAME ('S'), "vi$_big_s", vi$cmd_keys); DEFINE_KEY ("vi$_to_char (0)", KEY_NAME ('t'), "vi$_to_char (0)", vi$cmd_keys); DEFINE_KEY ("vi$_back_to_char (0)", KEY_NAME ('T'), "vi$_back_to_char (0)", vi$cmd_keys); DEFINE_KEY ("vi$perform_undo", KEY_NAME ('u'), "vi$perform_undo", vi$cmd_keys); DEFINE_KEY ("vi$undo_one_line", KEY_NAME ('U'), "vi$undo_one_line", vi$cmd_keys); DEFINE_KEY ("vi$_word_forward", KEY_NAME ('w'), "vi$_word_forward", vi$cmd_keys); DEFINE_KEY ("vi$_full_word_forward", KEY_NAME ('W'), "vi$_full_word_forward", vi$cmd_keys); DEFINE_KEY ("vi$do_macro ('dl', 0)", KEY_NAME ('x'), "vi$do_macro ('dl', 0)", vi$cmd_keys); DEFINE_KEY ("vi$do_macro ('dh', 0)", KEY_NAME ('X'), "vi$do_macro ('dh', 0)", vi$cmd_keys); DEFINE_KEY ("vi$_yank (0, -1)", KEY_NAME ('y'), "vi$_yank (0, -1)", vi$cmd_keys); DEFINE_KEY ("vi$_yank (KEY_NAME('y'), -1)", KEY_NAME ('Y'), "vi$_yank (KEY_NAME('y'), -1)", vi$cmd_keys); DEFINE_KEY ("vi$_ZZ", KEY_NAME ('Z'), "vi$_ZZ", vi$cmd_keys); DEFINE_KEY ("vi$_z_move", KEY_NAME ('z'), "vi$_z_move", vi$cmd_keys); DEFINE_KEY ("vi$_to_column", KEY_NAME ('|'), "vi$_to_column", vi$cmd_keys); DEFINE_KEY ("vi$_next_line", RET_KEY, "vi$_next_line", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('0'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('1'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('2'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('3'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('4'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('5'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('6'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('7'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('8'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$repeat_count", KEY_NAME ('9'), "vi$repeat_count", vi$cmd_keys); DEFINE_KEY ("vi$move_left", F12, "vi$move_left", vi$cmd_keys); DEFINE_KEY ("vi$move_left", LEFT, "vi$move_left", vi$cmd_keys); DEFINE_KEY ("vi$move_right", RIGHT, "vi$move_right", vi$cmd_keys); DEFINE_KEY ("vi$move_up", UP, "vi$move_up", vi$cmd_keys); DEFINE_KEY ("vi$move_down", DOWN, "vi$move_down", vi$cmd_keys); DEFINE_KEY ("vi$move_left", DEL_KEY, "vi$move_left", vi$cmd_keys); DEFINE_KEY ("vi$move_right", KEY_NAME (' '), "vi$move_right", vi$cmd_keys); DEFINE_KEY ("vi$ex_mode", DO, "vi$ex_mode", vi$cmd_keys); DEFINE_KEY ("vi$ex_mode", KEY_NAME(':'), "vi$ex_mode", vi$cmd_keys); DEFINE_KEY ("vi$_repeat_torf_back", KEY_NAME(','), "vi$_repeat_torf_back", vi$cmd_keys); DEFINE_KEY ("vi$_repeat_torf", KEY_NAME(';'), "vi$_repeat_torf", vi$cmd_keys); DEFINE_KEY ("vi$_search(1)", KEY_NAME('/'), "vi$_search(1)", vi$cmd_keys); DEFINE_KEY ("vi$_search(-1)", KEY_NAME('?'), "vi$_search(-1)", vi$cmd_keys); DEFINE_KEY ("vi$_eol", KEY_NAME('$'), "vi$_eol", vi$cmd_keys); DEFINE_KEY ("vi$_bol", KEY_NAME('^'), "vi$_bol", vi$cmd_keys); DEFINE_KEY ("vi$do_macro(vi$last_keys, 0)", KEY_NAME('.'), "vi$do_macro(vi$last_keys, 0)", vi$cmd_keys); DEFINE_KEY ("vi$macro", KEY_NAME('@'), "vi$macro", vi$cmd_keys); DEFINE_KEY ("vi$repeat_subs", KEY_NAME('&'), "vi$repeat_subs", vi$cmd_keys) ; DEFINE_KEY ("vi$region_filter", KEY_NAME('!'), "vi$region_filter", vi$cmd_keys); ! Define all of the insert-mode keys vi$edit_keys := CREATE_KEY_MAP ("e_keys"); ! These maps are not really active, but the comment fields are used ! during the execution of "vi$while_not_esc". DEFINE_KEY ("vi$_dummy", F12, "bs", vi$edit_keys); DEFINE_KEY ("vi$_dummy", PF1, "escape", vi$edit_keys); DEFINE_KEY ("vi$_dummy", F11, "escape", vi$edit_keys); DEFINE_KEY ("vi$_dummy", KEY_NAME (ASCII(27)), "escape", vi$edit_keys); DEFINE_KEY ("vi$_dummy", KEY_NAME (ASCII(0)), "reinsert", vi$edit_keys); DEFINE_KEY ("vi$_dummy", RET_KEY, "eol", vi$edit_keys); DEFINE_KEY ("vi$_dummy", TAB_KEY, "tab", vi$edit_keys); DEFINE_KEY ("vi$_dummy", CTRL_H_KEY, "bs", vi$edit_keys); DEFINE_KEY ("vi$_dummy", CTRL_V_KEY, "vquote", vi$edit_keys); DEFINE_KEY ("vi$_dummy", CTRL_W_KEY, "bword", vi$edit_keys); DEFINE_KEY ("vi$_dummy", DEL_KEY, "bs", vi$edit_keys); ! Define all of the delete mode mappings vi$move_keys := CREATE_KEY_MAP ("m_keys"); DEFINE_KEY ("vi$downline(1)", RET_KEY, "vi$downline(1)", vi$move_keys); DEFINE_KEY ("vi$right", KEY_NAME (" "), "vi$right", vi$move_keys); DEFINE_KEY ("vi$eol", KEY_NAME("$"), "vi$eol", vi$move_keys); DEFINE_KEY ("vi$to_marker", KEY_NAME ("'"), "vi$to_marker", vi$move_keys); DEFINE_KEY ("vi$to_marker", KEY_NAME ("`"), "vi$to_marker", vi$move_keys); DEFINE_KEY ("vi$first_no_space", KEY_NAME("^"), "vi$first_no_space", vi$move_keys); DEFINE_KEY ("vi$fol", KEY_NAME("0"), "vi$fol", vi$move_keys); DEFINE_KEY ("vi$upline", KEY_NAME ("-"), "vi$upline", vi$move_keys); DEFINE_KEY ("vi$downline(1)", KEY_NAME ("+"), "vi$downline(1)", vi$move_keys); DEFINE_KEY ("vi$search(1)", KEY_NAME ("/"), "vi$search(1)", vi$move_keys); DEFINE_KEY ("vi$search(-1)", KEY_NAME ("?"), "vi$search(-1)", vi$move_keys) ; DEFINE_KEY ("vi$match_brackets", KEY_NAME ("%"), "vi$match_brackets", vi$move_keys); DEFINE_KEY ("vi$full_word_move(-1)", KEY_NAME ("B"), "vi$full_word_move(-1)", vi$move_keys); DEFINE_KEY ("vi$word_move(-1)", KEY_NAME ("b"), "vi$word_move(-1)", vi$move_keys); DEFINE_KEY ("vi$_dummy", KEY_NAME ("c"), "vi$_dummy", vi$move_keys); DEFINE_KEY ("vi$word_end", KEY_NAME ("e"), "vi$word_end", vi$move_keys); DEFINE_KEY ("vi$full_word_end", KEY_NAME ("E"), "vi$full_word_end", vi$move_keys); DEFINE_KEY ("vi$back_find_char(0)", KEY_NAME ("F"), "vi$back_find_char(0)", vi$move_keys); DEFINE_KEY ("vi$find_char(0)", KEY_NAME ("f"), "vi$find_char(0)", vi$move_keys); DEFINE_KEY ("vi$to_line (vi$active_count)", KEY_NAME ("G"), "vi$to_line (vi$active_count)", vi$move_keys); DEFINE_KEY ("vi$to_home", KEY_NAME ("H"), "vi$to_home", vi$move_keys); DEFINE_KEY ("vi$left", KEY_NAME ("h"), "vi$left", vi$move_keys); DEFINE_KEY ("vi$downline(1)", KEY_NAME ("j"), "vi$downline(1)", vi$move_keys); DEFINE_KEY ("vi$upline", KEY_NAME ("k"), "vi$upline", vi$move_keys); DEFINE_KEY ("vi$right", KEY_NAME ("l"), "vi$right", vi$move_keys); DEFINE_KEY ("vi$to_middle", KEY_NAME ("M"), "vi$to_middle", vi$move_keys); DEFINE_KEY ("vi$to_last", KEY_NAME ("L"), "vi$to_last", vi$move_keys); DEFINE_KEY ("vi$search_next(vi$last_search_dir)", KEY_NAME('n'), "vi$search_next(vi$last_search_dir)", vi$move_keys); DEFINE_KEY ("vi$search_next(-vi$last_search_dir)", KEY_NAME('N'), "vi$search_next(-vi$last_search_dir)", vi$move_keys); DEFINE_KEY ("vi$to_char(0)", KEY_NAME ("t"), "vi$to_char(0)", vi$move_keys) ; DEFINE_KEY ("vi$back_to_char(0)", KEY_NAME ("T"), "vi$back_to_char(0)", vi$move_keys); DEFINE_KEY ("vi$word_move(1)", KEY_NAME ("w"), "vi$word_move(1)", vi$move_keys); DEFINE_KEY ("vi$full_word_move(1)", KEY_NAME ("W"), "vi$full_word_move(1)", vi$move_keys); DEFINE_KEY ("vi$downline", KEY_NAME(">"), "vi$downline(0)", vi$move_keys); DEFINE_KEY ("vi$downline", KEY_NAME("<"), "vi$downline(0)", vi$move_keys); DEFINE_KEY ("vi$downline(0)", KEY_NAME("d"), "vi$downline(0)", vi$move_keys); DEFINE_KEY ("vi$downline(0)", KEY_NAME("y"), "vi$downline(0)", vi$move_keys); DEFINE_KEY ("vi$downline(0)", KEY_NAME("!"), "vi$downline(0)", vi$move_keys); DEFINE_KEY ("vi$to_column", KEY_NAME ('|'), "vi$to_column", vi$move_keys); DEFINE_KEY ("vi$repeat_torf", KEY_NAME(';'), "vi$repeat_torf", vi$move_keys); DEFINE_KEY ("vi$repeat_torf_back", KEY_NAME(','), "vi$repeat_torf_back", vi$move_keys); DEFINE_KEY ("vi$paragraph (1)", KEY_NAME ('}'), "vi$paragraph (1)", vi$move_keys); DEFINE_KEY ("vi$section (1)", KEY_NAME (']'), "vi$section (1)", vi$move_keys); DEFINE_KEY ("vi$end_sentence", KEY_NAME (')'), "vi$end_sentence", vi$move_keys); DEFINE_KEY ("vi$paragraph (-1)", KEY_NAME ('{'), "vi$paragraph (-1)", vi$move_keys); DEFINE_KEY ("vi$section (-1)", KEY_NAME ('['), "vi$section (-1)", vi$move_keys); DEFINE_KEY ("vi$begin_sentence", KEY_NAME ('('), "vi$begin_sentence", vi$move_keys); ENDPROCEDURE; ! ! This procedure is called by the CTRL-` keystroke to swap the current ! buffer with the previous one. ! PROCEDURE vi$move_prev_buf LOCAL outf, buf; IF (vi$last_mapped = 0) OR (GET_INFO (vi$last_mapped, "TYPE") <> BUFFER) THEN MESSAGE ("No alternate buffer!"); RETURN; ENDIF; buf := vi$last_mapped; vi$check_auto_write; MAP (CURRENT_WINDOW, buf); vi$set_status_line (CURRENT_WINDOW); vi$pos_in_middle (MARK (NONE)); outf := GET_INFO (CURRENT_BUFFER, "OUTPUT_FILE"); IF outf = 0 THEN outf := GET_INFO (CURRENT_BUFFER, "NAME"); ENDIF; MESSAGE ('"'+outf+'"'); ENDPROCEDURE; ! ! This procedure is used to return the current mark in the buffer, after ! moving to the mark passed. This routine is used by the majority of the ! procedures that perform movement, and then return the location they ! stopped at, but do not change the current location in the buffer. ! PROCEDURE vi$retpos (pos) LOCAL endpos; ON_ERROR ENDON_ERROR endpos := MARK (NONE); ! If the marker is zero, then there is no way to position to it. IF (pos <> 0) THEN POSITION (pos); ENDIF; RETURN (endpos); ENDPROCEDURE; ! ! This procedure is called whenever ESCAPE is pressed while in command mode. ! The current active count should be zeroed, and possibly other things. ! PROCEDURE vi$on_escape vi$active_count := 0; vi$beep; ENDPROCEDURE; ! ! ! ! PROCEDURE vi$do_help (init_command) LOCAL buf, win; buf := CURRENT_BUFFER; MAP (info_window, show_buffer); HELP_TEXT ("vi$root:[doc]vi.hlb","VI " + init_command,ON,show_buffer); UNMAP (info_window); POSITION (buf); ENDPROCEDURE; ! ! This is the main processing loop, this function should never be exited. ! This means that the TPU "ABORT" builtin can not be used anywhere. ! PROCEDURE vi$command_mode (l_key) LOCAL key, last_len, win, cwin, pos, prog; IF (NOT vi$min_update) THEN UPDATE (CURRENT_WINDOW); ENDIF; ! Get the key to process. key := l_key; vi$push_a_key (key); vi$last_key := key; ! Initialize macro level counter. vi$m_level := 0; ! Set up so that 'U' works. pos := MARK (NONE); MOVE_HORIZONTAL (-CURRENT_OFFSET); IF (vi$undo_line_mark <> MARK (NONE)) THEN vi$undo_line_mark := MARK (NONE); vi$undo_line_str := vi$current_line; ENDIF; POSITION (pos); ! Get that keys program. prog := LOOKUP_KEY (KEY_NAME (key), PROGRAM, vi$cmd_keys); ! If prog = 0 then key is undefined, so ignore it. IF (prog <> 0) THEN vi$command_type := VI$OTHER_TYPE; ! Otherwise, do the program for that key. EXECUTE (prog); ! If this is a key that can change the buffer, then ! save the sequence of keys so that '.' causes them to ! be repeated. IF (INDEX (vi$dot_keys, ASCII (key)) <> 0) THEN vi$copy_keys (vi$last_keys, vi$cur_keys); ENDIF; ENDIF; ! Make sure we are not past end of line or at EOB. vi$check_rmarg; IF (INDEX ("0123456789", ASCII (key)) = 0) OR (vi$active_count = 0) THEN ERASE (vi$cur_keys); ENDIF; ENDPROCEDURE; ! ! Perform a macro command string that is either a string, or a buffer ! containing KEY_NAME values (as in execution of the '.' command). ! PROCEDURE vi$do_macro (commands, save_buffer) LOCAL typ, old_global, pos, key, prog; IF (vi$m_level > 30) THEN MESSAGE ("Infinite loop detected in key macro sequence!"); RETURN; ENDIF; vi$m_level := vi$m_level + 1; pos := MARK (NONE); ! If "commands" is a string then we must generate a buffer to ! place the commands into so that they can be read with "vi$read_a_key". IF (GET_INFO (commands, "TYPE") = STRING) THEN IF (vi$tmp_key_buf = 0) THEN vi$tmp_key_buf := vi$init_buffer ("$$tmp_key_buf$$", ""); ELSE ERASE (vi$tmp_key_buf); ENDIF; IF vi$tmp_key_buf = 0 THEN vi$message ("Can't do key macro: "+commands); RETURN; ENDIF; vi$str_to_keybuf (commands, vi$tmp_key_buf); vi$insert_macro_keys (vi$tmp_key_buf); ELSE vi$insert_macro_keys (commands); ENDIF; POSITION (pos); IF vi$undo_map THEN old_global := vi$in_global; vi$in_global := 0; IF (save_buffer AND (NOT old_global)) THEN vi$save_for_undo (CURRENT_BUFFER, VI$LINE_MODE, 1); vi$in_global := 1; ELSE IF old_global THEN vi$in_global := 1; ENDIF; ENDIF; ENDIF; LOOP ! Stop when all levels of macro are completed. EXITIF (vi$key_buf = 0); key := vi$read_a_key; ! Get that keys program. prog := LOOKUP_KEY (KEY_NAME (key), PROGRAM, vi$cmd_keys); ! If prog = 0 then key is undefined, so ignore it. IF (prog <> 0) THEN ! Otherwise, do the program for that key. EXECUTE (prog); ELSE MESSAGE ("Key '"+key+"' is undefined!"); vi$abort (0); ENDIF; ENDLOOP; IF (vi$in_global) THEN vi$undo_start := BEGINNING_OF (CURRENT_BUFFER); vi$undo_end := END_OF (CURRENT_BUFFER); vi$in_global := old_global; ENDIF; ENDPROCEDURE; ! ! This function handles the macro capability that allows the text in ! a named or numbered buffer to be executed as a sequence of commands ! by type an '@' and then the letter or number indicating the buffer to ! execute the contents of. ! PROCEDURE vi$macro LOCAL line, buf_name, bpos, cnt, ccnt, pos, buf, mode, ch; IF (vi$m_level > 30) THEN MESSAGE ("Infinite loop detected in macro key sequence!"); RETURN; ENDIF; vi$m_level := vi$m_level + 1; ch := vi$read_a_key; IF (INDEX ("123456789", ASCII(ch)) <> 0) THEN ! Selected a deletion buffer. buf_name := "vi$del_buf_"+ASCII(ch); ELSE IF (INDEX (vi$_letter_chars, ASCII(ch)) <> 0) THEN ! Selected a named buffer. IF (INDEX (vi$_upper_chars, ASCII(ch)) <> 0) THEN ch := SUBSTR (vi$_lower_chars, INDEX (vi$_upper_chars, ASCII(ch)), 1); ENDIF; buf_name := "vi$ins_buf_"+ASCII(ch); ELSE vi$message ("Invalid buffer!"); RETURN; ENDIF; ENDIF; vi$global_var := 0; EXECUTE (COMPILE ("vi$global_var := "+buf_name+";")); buf := vi$global_var; IF (buf = 0) THEN vi$message ("There is no text in that buffer!"); RETURN; ENDIF; pos := MARK (NONE); POSITION (BEGINNING_OF (buf)); ! Skip the buffer mode indicator. mode := INT (vi$current_line); MOVE_VERTICAL (1); cnt := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT") - 2; ccnt := 0; LOOP line := vi$current_line; IF (ccnt = cnt) THEN IF mode = VI$LINE_MODE THEN line := line + ASCII (13); ENDIF; ELSE line := line + ASCII (13); ENDIF; ccnt := ccnt + 1; bpos := MARK (NONE); POSITION (pos); vi$do_macro (line, 1); EXITIF (ccnt = cnt); pos := MARK (NONE); POSITION (bpos); MOVE_VERTICAL (1); ENDLOOP; ENDPROCEDURE; ! ! This procedure handles the operation of the U command. U undoes all ! changes performed on a line, providing the cursor has not left that ! line. ! PROCEDURE vi$undo_one_line LOCAL pos; pos := MARK (NONE); MOVE_HORIZONTAL (-CURRENT_OFFSET); IF (MARK (NONE) = vi$undo_line_mark) THEN ERASE_LINE; COPY_TEXT (vi$undo_line_str); SPLIT_LINE; MOVE_VERTICAL (-1); vi$kill_undo; vi$undo_end := 0; ELSE vi$undo_line_mark := 0; ENDIF; ENDPROCEDURE; ! ! This procedure takes a range or string of data, and squirrels it away ! to be restored when an undo operation is performed. ! PROCEDURE vi$save_for_undo (undo_data, btype, save_line_info) LOCAL pos; pos := MARK (NONE); IF (vi$in_global) THEN RETURN; ENDIF; IF (save_line_info) THEN vi$undo_line := vi$cur_line_no; vi$undo_offset := CURRENT_OFFSET; ELSE vi$undo_line := 0; ENDIF; IF vi$undo_buffer = 0 THEN vi$undo_buffer := vi$init_buffer ("$$vi$undo_buffer$$", ""); IF vi$undo_buffer = 0 THEN vi$message ("Error creating undo buffer!"); RETURN; ENDIF; ENDIF; vi$type2buf (STR (btype), vi$undo_buffer); vi$cp2buf (undo_data, vi$undo_buffer); vi$undo_valid := 1; POSITION (pos); ENDPROCEDURE; ! ! Disallow the data last saved with vi$save_for_undo() from being restored ! during an undo operation. ! PROCEDURE vi$kill_undo IF (NOT vi$in_global) THEN vi$undo_valid := 0; vi$undo_line := 0; ENDIF; ENDPROCEDURE; ! ! Perform the operation of undoing the last change. This operation is ! actually comprised of 3 separate operations. The first operation is ! to restore any text saved by vi$save_for_undo(). The next operation is ! to vi$save_for_undo() any text delimited by vi$undo_start and vi$undo_end. ! vi$undo_start marks the location where step 1 is performed. vi$undo_end ! determines whether or not there is text to save and then delete. If ! it has a non-zero value, then the range delimited by it and vi$undo_start ! is saved (using vi$save_for_undo()), and then deleted. ! PROCEDURE vi$perform_undo LOCAL done_pos, cbuf, pos, undo_line, undo_offset, cline, coff, btype, errno, undo_mode, saved_text, new_start, new_end, era_range; vi$new_offset := 1; new_start := 0; cline := vi$cur_line_no; coff := CURRENT_OFFSET; undo_line := vi$undo_line; undo_offset := vi$undo_offset; IF (GET_INFO (vi$undo_start, "BUFFER") <> CURRENT_BUFFER) OR ((NOT vi$undo_valid) AND (vi$undo_end = 0)) THEN vi$beep; RETURN; ENDIF; IF (vi$undo_valid) THEN cbuf := CURRENT_BUFFER; POSITION (BEGINNING_OF (vi$undo_buffer)); undo_mode := INT (vi$current_line); ERASE_LINE; POSITION (vi$undo_start); IF MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER) THEN new_start := 1; ELSE MOVE_HORIZONTAL (-1); new_start := MARK (NONE); MOVE_HORIZONTAL (1); ENDIF; SET (INSERT, CURRENT_BUFFER); COPY_TEXT (vi$undo_buffer); APPEND_LINE; MOVE_HORIZONTAL (-1); new_end := MARK (NONE); POSITION (BEGINNING_OF (vi$undo_buffer)); COPY_TEXT (STR (undo_mode)); SPLIT_LINE; POSITION (new_end); ENDIF; ! Use flag to determine whether or not to kill buffer contents. saved_text := 0; IF (vi$undo_start <> 0) AND (vi$undo_end <> 0) THEN saved_text := 1; pos := MARK (NONE); POSITION (vi$undo_end); IF (CURRENT_OFFSET <> 0) THEN btype := VI$IN_LINE_MODE; ELSE btype := VI$LINE_MODE; ENDIF; POSITION (pos); era_range := CREATE_RANGE (vi$undo_start, vi$undo_end, NONE); IF era_range <> 0 THEN POSITION (vi$undo_start); vi$save_for_undo (era_range, btype, 1); ERASE (era_range); ENDIF; ENDIF; IF (GET_INFO (new_start, "TYPE") <> INTEGER) THEN POSITION (new_start); vi$move_horizontal (1); vi$undo_start := MARK (NONE); vi$undo_end := new_end; ELSE IF new_start = 1 THEN vi$undo_start := BEGINNING_OF (CURRENT_BUFFER); vi$undo_end := new_end; ELSE vi$undo_end := 0; ENDIF; ENDIF; IF (saved_text = 0) THEN vi$kill_undo; ENDIF; IF (vi$undo_start <> 0) THEN POSITION (vi$undo_start); ENDIF; ! If undoing a macro then reposition to the place where we started. IF (undo_line <> 0) THEN vi$move_to_line (undo_line); vi$move_horizontal (undo_offset); vi$pos_in_middle (MARK (NONE)); vi$undo_line := undo_line; vi$undo_offset := undo_offset; ENDIF; vi$message (""); ENDPROCEDURE; ! ! This function performs the operations associated with the ^Y and ^E ! keystrokes. ! PROCEDURE vi$pull_push_line (direction) LOCAL currow, limit, n_lines, pos; ON_ERROR ! Ignore "ATTEMPT to move past TOP/BOTTOM of buffer" ENDON_ERROR; ! Get the number of lines to move. n_lines := vi$cur_active_count * direction; ! Mark the destination position for the case where we are at the top or ! bottom of the window. MOVE_VERTICAL (n_lines); pos := MARK (NONE); ! Return to the old position. MOVE_VERTICAL (-n_lines); ! Get the current screen row currow := GET_INFO (CURRENT_WINDOW, "CURRENT_ROW"); ! Get the proper border value based on the direction. IF (n_lines < 0) THEN limit := GET_INFO (CURRENT_WINDOW, "VISIBLE_BOTTOM"); ELSE limit := GET_INFO (CURRENT_WINDOW, "VISIBLE_TOP"); ENDIF; ! If we are NOT at the top or bottom, then the current row is the dest. IF (n_lines > 0) THEN IF (currow - limit) >= n_lines THEN pos := MARK (NONE); ENDIF; ELSE IF vi$abs (currow - limit) >= vi$abs (n_lines) THEN pos := MARK (NONE); ENDIF; ENDIF; ! Scroll the window. If the scroll fails, then move the cursor. IF (SCROLL (CURRENT_WINDOW, n_lines) <> n_lines) THEN MOVE_VERTICAL (n_lines); ELSE ! Otherwise the position we wanted is visible, so move there. POSITION (pos); IF (n_lines < 0) AND ((currow - limit) > n_lines) THEN MOVE_VERTICAL (limit - currow); ENDIF; ENDIF; ENDPROCEDURE; ! ! Move to the location indicated by a '|' command. ! PROCEDURE vi$_to_column vi$position (vi$to_column, 0); ENDPROCEDURE; ! ! Return the marker indicating the column selected by vi$active_count ! PROCEDURE vi$to_column LOCAL pos, act_count; act_count := vi$cur_active_count; pos := MARK (NONE); IF (act_count <= LENGTH (vi$current_line)) THEN pos := MARK (NONE); MOVE_HORIZONTAL (act_count - CURRENT_OFFSET - 1); RETURN (vi$retpos (pos)); ENDIF; RETURN (0); ENDPROCEDURE; ! ! Perform the operations associated with 'ZZ' (write and exit) command. ! PROCEDURE vi$_ZZ LOCAL prcnam, ans, cur_buf, buf, errno; ON_ERROR errno := ERROR; IF errno = TPU$_NOPARENT THEN ! Use vi$quit so that buffers not written will not be written ! automatically. vi$quit; ENDIF; ENDON_ERROR; IF (vi$read_a_key = KEY_NAME ('Z')) THEN cur_buf := CURRENT_BUFFER; vi$message (""); IF (GET_INFO (cur_buf, "MODIFIED")) AND (GET_INFO (cur_buf, "NO_WRITE") = 0) AND (GET_INFO (cur_buf, "SYSTEM") = 0) THEN vi$message ("Writing out """+GET_INFO (cur_buf, "NAME")+""""); WRITE_FILE (cur_buf); ENDIF; buf := GET_INFO (BUFFERS, "FIRST"); LOOP EXITIF (buf = 0); IF (GET_INFO (buf, "MODIFIED")) AND (GET_INFO (buf, "NO_WRITE") = 0) AND (GET_INFO (buf, "SYSTEM") = 0) THEN ans := vi$read_line ("Write """+GET_INFO (buf, "NAME")+"""? "); CHANGE_CASE (ans, LOWER); IF SUBSTR (ans, 1, 1) = "y" THEN vi$message ("Writing out """+GET_INFO (buf, "NAME")+""""); WRITE_FILE (buf); ENDIF; ENDIF; buf := GET_INFO (BUFFERS, "NEXT"); ENDLOOP; IF (vi$get_attach_parm ("TPU$NOSUBPROC") = " ") THEN prcnam := vi$get_attach_parm ("TPU$ATTACH_NAME"); vi$pasthru_off; IF (prcnam = " ") THEN ATTACH; ELSE ATTACH (prcnam); ENDIF; vi$pasthru_on; vi$process_args; ELSE vi$do_quit ("q", "q"); ENDIF; ENDIF; vi$kill_undo; vi$undo_end := 0; vi$active_count := 0; ENDPROCEDURE; ! ! Process the job logical names that are used to pass parameters between ! the parent process and the editor. ! PROCEDURE vi$process_args LOCAL buf, bufn, errno, startup_cmd, new_output, find_text, new_lineno, input_file; ON_ERROR errno := ERROR; SET (SUCCESS, ON); vi$system_message (errno); RETURN; ENDON_ERROR; startup_cmd := vi$get_attach_parm ("TPU$NEWCMD"); IF startup_cmd = " " THEN input_file := vi$get_attach_parm ("TPU$ARGS"); IF (input_file <> " ") THEN new_output := vi$get_attach_parm ("TPU$OUTPUT"); ! When a file is specified, and a new output file is also ! specified, then we will attempt to erase any existing ! buffer's contents so that MAIL will actually be able to ! be used over and over during an editor's life. IF (new_output <> " ") THEN bufn := FILE_PARSE (input_file,"","",NAME) + FILE_PARSE (input_file,"","",TYPE); buf := vi$find_buffer_by_name (bufn); IF buf <> 0 THEN IF (GET_INFO (buf, "MODIFIED") = 0) OR GET_INFO (buf, "NO_WRITE") THEN ERASE (buf); ELSE MESSAGE ( "Buffer is modified, original contents not destroyed!"); ENDIF; ENDIF; ENDIF; vi$get_file (input_file); IF (new_output <> " ") THEN SET (OUTPUT_FILE, CURRENT_BUFFER, new_output); vi$status_lines (CURRENT_BUFFER); ! Set the buffer to be modified so that the file will ! be written on exit. SPLIT_LINE; APPEND_LINE; ENDIF; ENDIF; ELSE new_output := vi$get_attach_parm ("TPU$OUTPUT"); IF (new_output <> " ") THEN SET (OUTPUT, CURRENT_BUFFER, new_output); vi$status_lines (CURRENT_BUFFER); ! Set the buffer to be modified so that the file will ! be written on exit. SPLIT_LINE; APPEND_LINE; ENDIF; vi$do_cmd_line (startup_cmd); ENDIF; new_lineno := vi$get_attach_parm ("TPU$LINE"); IF (new_lineno = " ") THEN find_text := vi$get_attach_parm ("TPU$SEARCH"); IF (find_text <> " ") THEN IF SUBSTR (find_text, 1, 1) = "/" THEN SET (FORWARD, CURRENT_BUFFER); vi$last_search_dir := 1; ELSE SET (REVERSE, CURRENT_BUFFER); vi$last_search_dir := -1; ENDIF; vi$search_string := SUBSTR (find_text, 2, LENGTH (find_text)-1); vi$position (vi$find_str (vi$search_string, 0), 1); ENDIF; ELSE vi$position (vi$to_line (INT (new_lineno)), 1); ENDIF; ENDPROCEDURE; ! ! A special procedure to trap any errors in translating logical names, and ! just ignore them, and return a " " string on error. ! PROCEDURE vi$get_attach_parm (parm) LOCAL rstr, errno, blank; ON_ERROR errno := ERROR; RETURN (blank); ENDON_ERROR; blank := " "; rstr := CALL_USER (vi$cu_trnlnm_job, parm); RETURN (rstr); ENDPROCEDURE; ! ! Perform the operations associated with the 'z' key command. ! PROCEDURE vi$_z_move LOCAL pos, crow, old_scroll, scrl_value, scroll_top, scroll_bottom, scroll_amount, act_count, done, next_key, cur_window; vi$active_count := 0; LOOP next_key := vi$read_a_key; EXITIF INDEX (vi$_numeric_chars, ASCII (next_key)) = 0; vi$active_count := vi$active_count * 10 + INT (ASCII (KEY_NAME (next_key))); ENDLOOP; IF (next_key = F11) OR ((next_key <> RET_KEY) AND (next_key <> KEY_NAME ('.')) AND (next_key <> KEY_NAME ('+')) AND (next_key <> KEY_NAME ('-'))) THEN vi$active_count := 0; RETURN; ENDIF; IF (vi$active_count > 0) AND (next_key <> KEY_NAME ('.')) THEN vi$old_place := MARK (NONE); pos := vi$to_line (vi$active_count); ELSE pos := MARK (NONE); ENDIF; cur_window := CURRENT_WINDOW; scroll_top := GET_INFO (cur_window, "SCROLL_TOP"); scroll_bottom := GET_INFO (cur_window, "SCROLL_BOTTOM"); scroll_amount := GET_INFO (cur_window, "SCROLL_AMOUNT"); done := 0; IF next_key = KEY_NAME ('-') THEN scrl_value := (GET_INFO (cur_window, "VISIBLE_LENGTH") / 2); SET (SCROLLING, cur_window, ON, scrl_value, scrl_value, scrl_value); POSITION (pos); vi$update (cur_window); done := 1; ELSE IF next_key = KEY_NAME ('+') THEN scrl_value := GET_INFO (cur_window, "VISIBLE_LENGTH"); SET (SCROLLING, cur_window, ON, scrl_value, scrl_value, scrl_value) ; POSITION (pos); vi$update (cur_window); done := 1; ELSE IF next_key = RET_KEY THEN scrl_value := GET_INFO (cur_window, "VISIBLE_LENGTH"); SET (SCROLLING, cur_window, ON, 0, scrl_value, scrl_value); POSITION (pos); vi$update (cur_window); done := 1; ELSE IF next_key = KEY_NAME ('.') THEN vi$do_set_window (vi$cur_active_count); vi$pos_in_middle (MARK (NONE)); MESSAGE (""); done := 0; ENDIF; ENDIF; ENDIF; ENDIF; IF (done) THEN SET (SCROLLING, cur_window, ON, scroll_top, scroll_bottom, scroll_amount); ENDIF; ENDPROCEDURE; ! ! Perform the 'r' command ! PROCEDURE vi$_replace_char LOCAL act_cnt, key, pos; ON_ERROR; POSITION (pos); RETURN; ENDON_ERROR; pos := MARK (NONE); act_cnt := vi$cur_active_count; IF (vi$show_mode) THEN vi$mess_select (BOLD); MESSAGE (FAO ("!7* REPLACE")); vi$mess_select (REVERSE); ENDIF; key := vi$read_a_key; IF (key = F11) THEN IF (vi$show_mode) THEN MESSAGE (""); $$EOD$$