home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 16 / 16.iso / w / w055 / 4.ddi / SOURCES.LIF / WORDSTAR.PEL < prev    next >
Encoding:
Text File  |  1990-09-27  |  27.9 KB  |  974 lines

  1. # $Header:   P:/source/ppee/macros/wordstar.pev   1.32   03 Jul 1990 14:56:22   milow  $
  2.  
  3. ##############################################################################
  4. #
  5. #           Sage Software - POLYTRON Division
  6. #             1700 NW 167th Place
  7. #               Beaverton, OR 97006
  8. #
  9. #   Copyright 1990, Sage Software, Inc.
  10. #
  11. #   Permission is hereby granted for licensed users of Sage Professional
  12. #   Editor and PolyAwk to copy and modify this source code for their own
  13. #   personal use.  These derivative works may be distributed only to other
  14. #   licensed Sage Professional Editor and PolyAwk users.  All other usage
  15. #   is prohibited without express written permission from Sage Software.
  16. #
  17. ##############################################################################
  18.  
  19. #### $Workfile:   wordstar.pel  $: Key bindings for WordStar compatability
  20.  
  21. ##
  22. ## wordstar() - define WordStar key bindings
  23. ##
  24.  
  25. local wordDefStr = "<|\\(|\\)|,|$"
  26. local previous_mst
  27.  
  28. local wordstar_keymap = -1
  29.  
  30. global function wordstar() {
  31.  
  32.     emulation_mode = "wordstar"
  33.     execute_event_handler(EVENT_EMULATION_CHANGED)
  34.  
  35.     toggle_dialog( TRUE )
  36.     toggle_file_backup( TRUE )
  37.     reset_visibles()
  38.     default_visible_virtual_lines = "~"
  39.     visible_virtual_lines = "~"
  40.  
  41.     default_window_flags =                 \
  42.         nominal_border_flags =             \
  43.             WINDOW_STANDARD
  44.  
  45.     if ( !and( window_flags, WINDOW_SYSTEM ))
  46.         window_flags = default_window_flags
  47.  
  48.     search_flags =             \
  49.         + SEARCH_MAXIMAL_MATCH            \
  50.         + SEARCH_FORWARD            \
  51.         + SEARCH_REGEX                \
  52. #        + SEARCH_ADVANCE        \
  53. #        + SEARCH_HIGHLIGHT
  54.  
  55.     previous_mst = mouse_selection_type
  56.     mouse_selection_type = NORMAL_SELECTION
  57.     attach_event_handler(EVENT_EMULATION_CHANGED,function_id("ws_restore"))
  58.  
  59.     # Enable the keymap.  Subsequent mods to the keymap will persist 
  60.     #     through the end of the session. 
  61.     # Only one-time initialization should follow this point. 
  62.  
  63.     if( wordstar_keymap >= 0 ){
  64.         current_keymap = wordstar_keymap
  65.         return
  66.     }
  67.  
  68.     wordstar_keymap = current_keymap = create_keymap( factory_keymap )
  69.  
  70.     #--------------------------------------------------------------
  71.     # Mouse commands
  72.     #--------------------------------------------------------------
  73.     assign_mouse_buttons()
  74.  
  75.     #--------------------------------------------------------------
  76.     # Basic Text commands
  77.     #--------------------------------------------------------------
  78.     assign_key("<Ctrl-N>",        "ws_open_newline")
  79.     assign_key("<Ctrl-Q><Ctrl-Y>",    "delete_to_eol")
  80.     assign_key("<Ctrl-Q>y",        "delete_to_eol")
  81.     assign_key("<Ctrl-Q>Y",        "delete_to_eol")
  82.     assign_key("<Ctrl-Y>",        "delete_line")
  83.     assign_key("<Shift-Tab>",    "outdent_tab_maybe")
  84.     assign_key("<Tab>",        "indent_tab_maybe")
  85.     assign_key("<Ctrl-G>",        "delete_chars")
  86.  
  87.     #--------------------------------------------------------------
  88.     # Macros and keystroke recordings
  89.     #--------------------------------------------------------------
  90.     assign_key("<F7>",        "record_key")
  91.     assign_key("<F8>",        "playback")
  92.  
  93.     #--------------------------------------------------------------
  94.     # Manipulating Buffers
  95.     #--------------------------------------------------------------
  96.     assign_key("<Alt-N>",        "next_buffer_key")
  97.     assign_key("<Alt-P>",        "prev_buffer_key")
  98.     assign_key("<F9>",        "compile_buffer")
  99.     assign_key("<Ctrl-Q>y",        "delete_to_eol")
  100.     assign_key("<Ctrl-Q>Y",        "delete_to_eol")
  101.     assign_key("<Ctrl-K>s",        "save_buffer")
  102.     assign_key("<Ctrl-K>S",        "save_buffer")
  103.     assign_key("<Ctrl-K><Ctrl-S>",    "save_buffer")
  104.     assign_key("<Ctrl-K>d",        "ws_quit 1 0 1")
  105.     assign_key("<Ctrl-K>D",        "ws_quit 1 0 1")
  106.     assign_key("<Ctrl-K><Ctrl-D>",    "ws_quit 1 0 1")
  107.     assign_key("<Ctrl-K>q",        "ws_abandon")
  108.     assign_key("<Ctrl-K>Q",        "ws_abandon")
  109.     assign_key("<Ctrl-K><Ctrl-Q>",    "ws_abandon")
  110.     assign_key("<Ctrl-K>x",        "ws_quit 1")
  111.     assign_key("<Ctrl-K>X",        "ws_quit 1")
  112.     assign_key("<Ctrl-K><Ctrl-X>",    "ws_quit 1")
  113.     assign_key("<Alt-Minus>",    "delete_buffer_key")
  114.  
  115.     #--------------------------------------------------------------
  116.     # Window Selection
  117.     #--------------------------------------------------------------
  118.     assign_key("<F4>",        "delete_window_key")
  119.     assign_key("<Alt-F1>",        "next_window")
  120.     assign_key("<Alt-F2>",        "prev_window")
  121.     assign_key("<Shift-F5>",    "larger_window")
  122.     assign_key("<Ctrl-F5>",        "smaller_window")
  123.     assign_key("<Shift-F9>",    "make_window")
  124.     assign_key("<Alt-F4>",        "delete_tiled_window")
  125.     assign_key("<Alt-F5>",        "create_tiled_window")
  126.  
  127.     #--------------------------------------------------------------
  128.     # Cursor Movement
  129.     #--------------------------------------------------------------
  130.     assign_key("<Ctrl-E>",        "up")
  131.     assign_key("<Ctrl-X>",        "down")
  132.     assign_key("<Ctrl-S>",        "left")
  133.     assign_key("<Ctrl-D>",        "right")
  134.     assign_key("<Ctrl-R>",        "page_up")
  135.     assign_key("<Ctrl-C>",        "page_down")
  136.     assign_key("<Ctrl-Q>s",        "goto_bol")
  137.     assign_key("<Ctrl-Q>S",        "goto_bol")
  138.     assign_key("<Ctrl-Q><Ctrl-S>",    "goto_bol")
  139.     assign_key("<Ctrl-Q>d",        "goto_eol")
  140.     assign_key("<Ctrl-Q>D",        "goto_eol")
  141.     assign_key("<Ctrl-Q><Ctrl-D>",    "goto_eol")
  142.     assign_key("<Ctrl-Q>r",        "goto_buffer_top")
  143.     assign_key("<Ctrl-Q>R",        "goto_buffer_top")
  144.     assign_key("<Ctrl-Q><Ctrl-R>",    "goto_buffer_top")
  145.     assign_key("<Ctrl-Q>c",        "goto_buffer_bottom")
  146.     assign_key("<Ctrl-Q>C",        "goto_buffer_bottom")
  147.     assign_key("<Ctrl-Q><Ctrl-C>",    "goto_buffer_bottom")
  148.     assign_key("<Ctrl-Q>e",        "topLeft")
  149.     assign_key("<Ctrl-Q>E",        "topLeft")
  150.     assign_key("<Ctrl-Q><Ctrl-E>",    "topLeft")
  151.     assign_key("<Ctrl-A>",        "ws_prev_word")
  152.     assign_key( "#8",    "outdent_space_maybe" )    # Ctrl-H or Backspace
  153.     assign_key("<Ctrl-F>",        "ws_next_word")
  154.     assign_key("<Ctrl-W>",        "scroll_up_1")
  155.     assign_key("<Ctrl-Z>",        "scroll_down_1")
  156.     assign_key("<Ctrl-Q>x",        "bottomRight")
  157.     assign_key("<Ctrl-Q>X",        "bottomRight")
  158.     assign_key("<Ctrl-Q><Ctrl-X>",    "bottomRight")
  159.     assign_key("<Ctrl-Q>l",        "goto_line_key")
  160.     assign_key("<Ctrl-Q>L",        "goto_line_key")
  161.     assign_key("<Ctrl-Q><Ctrl-L>",    "goto_line_key")
  162.     assign_key("<Ctrl-Left>",    "ws_prev_word")
  163.     assign_key("<Ctrl-Right>",    "ws_next_word")
  164.  
  165.     #--------------------------------------------------------------
  166.     # Marked Blocks
  167.     #--------------------------------------------------------------
  168.     assign_key("<Ctrl-K>i",        "ws_begin_block 4")
  169.     assign_key("<Ctrl-K>I",        "ws_begin_block 4")
  170.     assign_key("<Ctrl-K><Ctrl-I>",    "ws_begin_block 4")
  171.     assign_key("<Ctrl-K>l",        "ws_begin_block 3")
  172.     assign_key("<Ctrl-K>L",        "ws_begin_block 3")
  173.     assign_key("<Ctrl-K><Ctrl-L>",    "ws_begin_block 3")
  174.     assign_key("<Ctrl-K>n",        "ws_begin_block 2")
  175.     assign_key("<Ctrl-K>N",        "ws_begin_block 2")
  176.     assign_key("<Ctrl-K><Ctrl-N>",    "ws_begin_block 2")
  177.     assign_key("<Ctrl-K>b",        "ws_begin_block")
  178.     assign_key("<Ctrl-K>B",        "ws_begin_block")
  179.     assign_key("<Ctrl-K><Ctrl-B>",    "ws_begin_block")
  180.     assign_key("<Keypad-+>",    "ws_copy_block")
  181.     assign_key("<Ctrl-K>k",        "ws_copy_block")
  182.     assign_key("<Ctrl-K>K",        "ws_copy_block")
  183.     assign_key("<Ctrl-K><Ctrl-K>",    "ws_copy_block")
  184.     assign_key("<Ctrl-K>c",        "ws_insert_scrap")
  185.     assign_key("<Ctrl-K>C",        "ws_insert_scrap")
  186.     assign_key("<Ctrl-K><Ctrl-C>",    "ws_insert_scrap")
  187.     assign_key("<Ctrl-K>v",        "ws_move_block")
  188.     assign_key("<Ctrl-K>V",        "ws_move_block")
  189.     assign_key("<Ctrl-K><Ctrl-V>",    "ws_move_block")
  190.     assign_key("<Ctrl-K>p",        "print_buffer")
  191.     assign_key("<Ctrl-K>P",        "print_buffer")
  192.     assign_key("<Ctrl-K><Ctrl-P>",    "print_buffer")
  193.     assign_key("<Ctrl-K>w",        "ws_write_file")
  194.     assign_key("<Ctrl-K>W",        "ws_write_file")
  195.     assign_key("<Ctrl-K><Ctrl-W>",    "ws_write_file")
  196.     assign_key("<Ctrl-K>r",        "ws_read_file")
  197.     assign_key("<Ctrl-K>R",        "ws_read_file")
  198.     assign_key("<Ctrl-K><Ctrl-R>",    "ws_read_file")
  199.     assign_key("<Ctrl-K>h",        "ws_toggle_marking")
  200.     assign_key("<Ctrl-K>H",        "ws_toggle_marking")
  201.     assign_key("<Ctrl-K><Ctrl-H>",    "ws_toggle_marking")
  202.     assign_key("<Ctrl-K>y",        "ws_delete_block")
  203.     assign_key("<Ctrl-K>Y",        "ws_delete_block")
  204.     assign_key("<Ctrl-K><Ctrl-Y>",    "ws_delete_block")
  205.     assign_key("<Ctrl-K>f",        "system_key")
  206.     assign_key("<Ctrl-K>F",        "system_key")
  207.     assign_key("<Ctrl-K><Ctrl-F>",    "system_key")
  208.     assign_key("<Ins>",        "ws_insert_scrap")
  209.     assign_key("<Minus>",        "ws_delete_block")
  210.  
  211.     #--------------------------------------------------------------
  212.     # Bookmarks
  213.     #--------------------------------------------------------------
  214.     assign_key("<Ctrl-K>1",        "place_bookmark 1")
  215.     assign_key("<Ctrl-K>2",        "place_bookmark 2")
  216.     assign_key("<Ctrl-K>3",        "place_bookmark 3")
  217.     assign_key("<Ctrl-K>4",        "place_bookmark 4")
  218.     assign_key("<Ctrl-K>5",        "place_bookmark 5")
  219.     assign_key("<Ctrl-K>6",        "place_bookmark 6")
  220.     assign_key("<Ctrl-K>7",        "place_bookmark 7")
  221.     assign_key("<Ctrl-K>8",        "place_bookmark 8")
  222.     assign_key("<Ctrl-K>9",        "place_bookmark 9")
  223.     assign_key("<Ctrl-K>0",        "place_bookmark 10")
  224.  
  225.     assign_key("<Ctrl-Q>1",        "goto_bookmark 1")
  226.     assign_key("<Ctrl-Q>2",        "goto_bookmark 2")
  227.     assign_key("<Ctrl-Q>3",        "goto_bookmark 3")
  228.     assign_key("<Ctrl-Q>4",        "goto_bookmark 4")
  229.     assign_key("<Ctrl-Q>5",        "goto_bookmark 5")
  230.     assign_key("<Ctrl-Q>6",        "goto_bookmark 6")
  231.     assign_key("<Ctrl-Q>7",        "goto_bookmark 7")
  232.     assign_key("<Ctrl-Q>8",        "goto_bookmark 8")
  233.     assign_key("<Ctrl-Q>9",        "goto_bookmark 9")
  234.     assign_key("<Ctrl-Q>0",        "goto_bookmark 10")
  235.  
  236.  
  237.     #--------------------------------------------------------------
  238.     # Search and Replace
  239.     #--------------------------------------------------------------
  240.     assign_key("<Ctrl-Q>f",        "ws_search_find")
  241.     assign_key("<Ctrl-Q>F",        "ws_search_find")
  242.     assign_key("<Ctrl-Q><Ctrl-F>",    "ws_search_find")
  243.     assign_key("<Ctrl-Q>a",        "ws_search_replace")
  244.     assign_key("<Ctrl-Q>A",        "ws_search_replace")
  245.     assign_key("<Ctrl-Q><Ctrl-A>",    "ws_search_replace")
  246.     assign_key("<Ctrl-Q>i",        "search_i")
  247.     assign_key("<Ctrl-Q>I",        "search_i")
  248.     assign_key("<Ctrl-Q><Ctrl-I>",    "search_i")
  249.     assign_key("<Ctrl-L>",        "ws_search_again")
  250.  
  251.     #--------------------------------------------------------------
  252.     # Miscellaneous
  253.     #--------------------------------------------------------------
  254.     assign_key("<Ctrl-T>",        "del_next_word")
  255.     assign_key("<Ctrl-P>",        "insert_quoted_key")
  256.     assign_key("<F10>",        "invoke_function")
  257.     assign_key("<Ctrl-V>",        "toggle_insert_mode")
  258.     assign_key("<Alt-U>",        "undo")
  259.     assign_key("<Keypad-*>",    "undo")
  260.     assign_key("<Alt-Y>",        "redo")
  261.     assign_key("<Alt-V>",        "print_version")
  262.     assign_key("<Ctrl-F7>",        "display_errors")
  263.     assign_key("<Alt-=>",        "goto_next_error")
  264.     assign_key("<Ctrl-B>",        "wrap_paragraph")
  265.     assign_key("<Alt-B>",        "buffer_list")
  266.     assign_key("<Alt-H>",        "help")
  267.     assign_key("`",            "expand_template")
  268.     assign_key("<Alt-M>",        "mark_matching")
  269.     assign_key( "<Space>",        "indent_outdent_space" )
  270.     assign_key( "<Alt-F7>",        "learn_key" )
  271.     assign_key( "#10",    "auto_indent_nl" )    # Ctrl-J or Ctrl-Enter
  272.     assign_key( "#13",    "auto_indent_cr" )    # Ctrl-M or Enter
  273.  
  274. }
  275.  
  276. ##
  277. ## turbo_local() - define Borland extensions to WordStar
  278. ##
  279.  
  280. global function turbo_local() {
  281.     assign_key("<Alt-F3>",        "buffer_list")
  282.     assign_key("<F2>",        "save_buffer")
  283.     assign_key("<F3>",        "edit_file_key")
  284.     assign_key("<Alt-X>",        "ws_quit 1 1")
  285.     assign_key("<Alt-F>o",        "system")
  286.     assign_key("<Alt-F>w",        "writeTo")
  287.     assign_key("<Alt-F>c",        "changeDir")
  288.     assign_key("<Alt-F>d",        "showDir")
  289.     assign_key("<F5>",        "toggle_window_zoom")
  290.     assign_key("<Ctrl-O>i",        "ai")
  291.     toggle_auto_indent(TRUE)
  292.     message_level = 0
  293. }
  294.  
  295. #---------------------------------------------------------------#
  296. #                                                               #
  297. #      Functions required to support the WordStar calls         #
  298. #                                                               #
  299. #---------------------------------------------------------------#
  300.  
  301.  
  302. #        topLeft()
  303. #
  304. #        This function moves the cursor to the top left of the current 
  305. #        window.
  306.  
  307. function topLeft() {
  308.     goto_window_top()
  309.     goto_bol()
  310. }
  311.  
  312.  
  313. #        bottomRight()
  314. #
  315. #        This function moves the cursor to the bottom right of the current 
  316. #        window.
  317.  
  318. function bottomRight() {
  319.     goto_window_bottom()
  320.     goto_eol()
  321. }
  322.  
  323.  
  324.  
  325. #        writeTo()
  326. #
  327. #        This function prompts the user for a new output filename and then 
  328. #        saves the current buffer to that name.
  329.  
  330. function writeTo() {
  331.     change_output_name()
  332.     save_buffer()
  333. }
  334.  
  335.  
  336. #        ws_open_newline()
  337. #
  338. #        This function opens a new line at the cursor position.  The cursor 
  339. #        does NOT move down to the new line.
  340.  
  341. function ws_open_newline() {
  342.     insert_newline()
  343.     up()
  344.     goto_eol()
  345. }
  346.  
  347. #        ws_abandon()
  348. #
  349. #        This is the WordStar function to abandon the current buffer.  If 
  350. #        there have been no modifications, the editor exits without further 
  351. #        adieu.  If there have been mods, the user is asked his/her 
  352. #        intentions.  If the user elects not to abandon the edits, the 
  353. #        editor returns to editing and does not exit or save.
  354.  
  355. function ws_abandon() {
  356.     while (buffers_modified) {
  357.         next_buffer()
  358.         if (buffer_is_modified()) {
  359.             if (toupper(confirm(sprintf("Buffer <%s> not saved.  Abandon? (Y/N)",
  360.                     buffer_name),"YyNn")) == "N") 
  361.                 return
  362.             else
  363.                 buffer_flags = set_flag_bits(buffer_flags, \
  364.                     BUFFER_MODIFIED,0)    
  365.         }
  366.     }
  367.     if (and(current_key,0x00FF) != 0x1b)
  368.         quit()
  369. }
  370.  
  371.  
  372. #        ws_quit()
  373. #
  374. #        This function handles WordStar's various other methods of exiting, 
  375. #        other than abandoning.  It allows saving all buffers and exiting 
  376. #        (a la <Ctrl-K>x), saving and moving on to the next file (a la 
  377. #        <Ctrl-K>d), or prompting to save each modified buffer and then 
  378. #        exiting (a la Borland's <Alt-X>.
  379.  
  380. function ws_quit(saving,prompting,newfile) {
  381.     if (buffers_modified && saving && !prompting)
  382.         message(sprintf("Saving %ld buffers... ",buffers_modified))
  383.     while (buffers_modified) {
  384.         next_buffer()
  385.         if (buffer_is_modified()) {
  386.             if (saving && (!(0+prompting) || 
  387.                     toupper(confirm(sprintf(    \
  388.                     "Verify:  Buffer <%s> not saved.  Save? (Y/N)", \
  389.                     buffer_name),"YyNn")) == "Y")) {
  390.                 if (filemode(buffer_filename) != -1)
  391.                     backup_file(buffer_filename)
  392.                 write_buffer()
  393.             } else {
  394.                 if (and(current_key,0x00FF) == 0x1b)
  395.                     return
  396.                 buffer_flags = set_flag_bits(buffer_flags,BUFFER_MODIFIED,0)
  397.             }
  398.         }
  399.     }
  400.     if (newfile)
  401.         edit_file_key()
  402.     else
  403.         if (and(current_key,0x00FF) != 0x1b)
  404.             quit()
  405. }
  406.  
  407.  
  408. #        del_next_word()
  409. #
  410. #        This function deletes the word following the cursor position.  The 
  411. #        characters that are used to define the beginning and end of a word 
  412. #        may be defined.
  413.  
  414. function del_next_word() {
  415.     if (drop_anchor()) {
  416.         ws_next_word()
  417.         delete_chars()
  418.     } else
  419.         beep()
  420. }
  421.  
  422.  
  423. #        ws_write_file()
  424. #
  425. #        This function allows writing a block to a file.  If the file 
  426. #        already exists the user may elect to overwrite it or abort the 
  427. #        write.
  428.  
  429. function ws_write_file() {
  430.     local filenameStr
  431.  
  432.     if ( region_type() != 0 || ws_toggle_marking()) {
  433.         filenameStr = prompt("File name:  ")
  434.         if (filemode(filenameStr) != -1) {
  435.             if (toupper(confirm("File " filenameStr "exists.  Overwrite? (Y/N) ",
  436.                 "YyNn")) == "Y")
  437.                 if (write_marked_block(filenameStr))
  438.                     message("Block written")
  439.                 else
  440.                     message("Error writing file.")
  441.         } else if (write_marked_block(filenameStr))
  442.             message("Block written")
  443.     } else
  444.         warning( "No block marked.")
  445. }
  446.  
  447.  
  448. #        ws_read_file()
  449. #
  450. #        This function allows reading a block from a file.  The user is 
  451. #        prompted for the name of the file to be read.
  452.  
  453. function ws_read_file() {
  454.     local start_line, start_col
  455.  
  456.     start_line = current_line
  457.     start_col = current_column
  458.     drop_anchor()
  459.     if (!read_file_key())
  460.         raise_anchor()
  461.     else {
  462.         goto_pos(start_line,start_col)
  463.         copy_to_scrap()
  464.         ws_toggle_marking()
  465.     }
  466. }
  467.  
  468. local sel_line = 0, sel_col = 0, pos_line = 0, pos_col = 0, sel_buf, sel_type
  469.  
  470.  
  471. #        ws_toggle_marking()
  472. #
  473. #        This function hides or reveals a marked block, if any.  This 
  474. #        function is very important to simulating the type of block marking 
  475. #        used by WordStar.  It is called by other functions that expect 
  476. #        there to be a marked block but find none.
  477.  
  478. function ws_toggle_marking() {
  479.     if (region_type() == 0) {
  480.         if (sel_line + sel_col) {
  481.             current_buffer = sel_buf
  482.             current_line = sel_line
  483.             current_column = sel_col
  484.             drop_anchor(sel_type)
  485.             goto_pos(pos_line,pos_col);
  486.             message("Block is revealed.")
  487.         } else
  488.             message("No hidden block defined.")
  489.     } else {
  490.         sel_line = mark_line()
  491.         sel_col = mark_column()
  492.         pos_line = current_line
  493.         pos_col = current_column
  494.         sel_buf = current_buffer
  495.         sel_type = region_type()
  496.         raise_anchor()
  497.         message("Block is hidden.")
  498.     }
  499.     return sel_line
  500. }
  501.  
  502.  
  503. #        reinit_selvars()
  504. #
  505. #        This function reinitializes the variables used to record the 
  506. #        nature and position of the hidden block.
  507.  
  508. function reinit_selvars() {
  509.     sel_line = sel_col = pos_line = pos_col = sel_type = 0;
  510. }
  511.  
  512.  
  513. #        ws_copy_block()
  514. #
  515. #        This is the function that copies a block to scrap when the end of 
  516. #        the block is defined (<Ctrl-K>k).
  517.  
  518. function ws_copy_block() {
  519.     if (region_type() != 0) {
  520.         copy_to_scrap()
  521.         ws_toggle_marking()
  522.         message("Block copied.")
  523.     } else {
  524.         if ((sel_line + sel_col) && sel_buf == current_buffer ) {
  525.             save_position()
  526.             current_line = sel_line
  527.             current_column = sel_col
  528.             drop_anchor(sel_type)
  529.             restore_position(TRUE)
  530.         } else
  531.             message("Beginning of block not defined.");
  532.     }
  533. }
  534.  
  535.  
  536. #        ws_move_block()
  537. #
  538. #        This function simulates the WordStar block move (<Ctrl-K>v).  It 
  539. #        restores a hidden block, deletes it and then inserts scrap at the 
  540. #        current position.
  541.  
  542. function ws_move_block() {
  543.     local save_buf
  544.  
  545.     save_buf = current_buffer
  546.     save_position()
  547.     if (ws_toggle_marking()) {
  548.         delete_chars()
  549.         current_buffer = save_buf
  550.         restore_position(TRUE)
  551.         ws_insert_scrap()
  552.         message("Block moved.")
  553.     } else {
  554.         restore_position(TRUE)
  555.         warning("No block to move.")
  556.     }
  557. }
  558.  
  559.  
  560. #        ws_delete_block()
  561. #
  562. #        This function simulates the WordStar block delete (<Ctrl-K>y.  The 
  563. #        hidden block is restored and then deleted to scrap.
  564.  
  565. function ws_delete_block() {
  566.     save_position()
  567.     if (ws_toggle_marking()) {
  568.         delete_to_scrap()
  569.         message("Block deleted to scrap")
  570.     } else
  571.         warning("No block defined.")
  572.     restore_position(TRUE)
  573.     reinit_selvars()
  574. }
  575.  
  576.  
  577. #        ws_insert_scrap()
  578. #
  579. #        This function inserts scrap and then restores the cursor position 
  580. #        to the beginning of the insertion.  (<Ctrl-K>c)
  581.  
  582. function ws_insert_scrap() {
  583.     local start_line, start_col
  584.  
  585.     start_line = current_line
  586.     start_col = current_column
  587.     insert_scrap()
  588.     reinit_selvars()
  589.     goto_pos(start_line,start_col)
  590. }
  591.  
  592.  
  593. #        ws_begin_block()
  594. #
  595. #        This is the function to begin a WordStar block.  If a block has 
  596. #        already been started, it is abandoned in favor of a new block.
  597.  
  598. function ws_begin_block( marktype ) {
  599.     if (!marktype)
  600.         marktype = NORMAL_SELECTION
  601.     if (region_type() != 0)
  602.         raise_anchor()
  603.     drop_anchor( marktype )
  604. }
  605.  
  606.  
  607. #        save_buffer()
  608. #
  609. #        This is the function to save a buffer and continue (<Ctrl-K>s)
  610.  
  611. function save_buffer() {
  612.     message("Saving buffer...")
  613.     if (filemode(buffer_filename) != -1 && buffer_is_modified())
  614.         backup_file(buffer_filename)
  615.     write_buffer()
  616.     message("Buffer saved.")
  617. }
  618.  
  619.  
  620. local dirStr = getcwd()
  621.  
  622.  
  623. #        changeDir()
  624. #
  625. #        This function provides the Borland extension to WordStar that 
  626. #        allows changing directories.
  627.  
  628. function changeDir() {
  629.     dirStr = prompt("Enter the new directory:  ",dirStr)
  630.     if (!chdir(dirStr))
  631.         warning("Cannot change to directory " dirStr)
  632.     else
  633.         message("Logged to:  " dirStr)
  634. }
  635.  
  636. local dirMask = "*.*"
  637.  
  638.  
  639. #        showDir()
  640. #
  641. #        This is the function that provides the Borland extension to 
  642. #        WordStar that allows getting a directory.
  643.  
  644. function showDir() {
  645.     dirMask = prompt("Enter the directory file mask:  ",dirMask)
  646.     system("dir " dirMask " /w")
  647. }
  648.  
  649.  
  650. #        ws_next_word()
  651. #
  652. #        This function moves the cursor to the following word, using our 
  653. #        own definition of the word's delimiting characters.
  654.  
  655. function ws_next_word() {
  656.     if (!next_word(1,wordDefStr))
  657.         goto_eol()
  658. }
  659.  
  660.  
  661.  
  662. #        ws_prev_word()
  663. #
  664. #        This function moves the cursor to the preceding word, using our 
  665. #        own definition of the word's delimiting characters.
  666.  
  667. function ws_prev_word() {
  668.     prev_word(1,wordDefStr)
  669. }
  670.  
  671.  
  672. #----------- Supporting search and replace functions ------------#
  673.  
  674. # reserved global variables
  675.  
  676. #local SEARCH_MARK
  677. local search_line, search_column, search_prompt
  678. local SEARCH_GLOBALLY = 99999
  679.  
  680.  
  681.  
  682. #        search_is_local()
  683. #
  684. #        This function tests to see if searches are currently set to be 
  685. #        limited to the defined block.
  686.  
  687. function search_is_local() {
  688.     return and(search_flags,SEARCH_BLOCK)
  689. }
  690.  
  691.  
  692. #        ws_replacing()
  693. #
  694. #        This function is the core of the replacement engine.  It takes 
  695. #        note of various flags and settings to search globally, locally 
  696. #        (within a block), and with or without prompting.
  697.  
  698. function ws_replacing(serStr,replStr) {
  699.     local    found_replacement = FALSE, ch, change_count = 0, save_count
  700.     local    local_offset, end_offset, lsearch_flags
  701.  
  702.     if (search_count == SEARCH_GLOBALLY) {
  703.         # save current position and restore later if successful
  704.         save_position()
  705.         if (search_is_local()) {
  706.             if (!region_type())
  707.                 if (!ws_toggle_marking()) {
  708.                     error("Block must be marked!")
  709.                     return
  710.                 }
  711.  
  712.             # make sure the cursor is at the beginning of the block
  713.             local_offset = buffer_offset
  714.             swap_marks()
  715.             if (local_offset < buffer_offset) {
  716.                 end_offset = buffer_offset
  717.                 swap_marks()
  718.             } else
  719.                 end_offset = local_offset
  720.             save_position()
  721.         }
  722.         search_count = 0;
  723.  
  724.         # turn search advance off so we find match at cursor.
  725.         lsearch_flags = set_flag_bits(search_flags,SEARCH_ADVANCE,0)
  726.         while ( search( serStr, lsearch_flags )) {
  727.             #
  728.             # highlight the search string found and update
  729.             # the screen
  730.             #
  731.             next_char( search_string_length )
  732.             drop_anchor()
  733.             prev_char( search_string_length )
  734.             display_update()
  735.             found_replacement = TRUE
  736.             if (search_prompt) {
  737.                 ch = tolower(confirm("Replace? (Y/N) ","YyNn"))
  738.                 raise_anchor()
  739.                 display_update()
  740.             } else {
  741.                 raise_anchor()
  742.                 while (replace(serStr, replStr, search_flags)) {
  743.                     if (!change_count)
  744.                         # if we found something, turn search advance on.
  745.                         search_flags = \
  746.                             set_flag_bits(search_flags,SEARCH_ADVANCE,SEARCH_ADVANCE)
  747.                     change_count++
  748.                 }
  749.                 setSearchPos()
  750.                 break
  751.             }
  752.             if (ch == "y") {
  753.                 # replace and prompt again for next
  754.                 search_flags = \
  755.                     set_flag_bits(search_flags,SEARCH_ADVANCE,0)
  756.                 _replace_current_item(serStr, replStr, search_flags)
  757.                 change_count++
  758.             } else if (ch == "n") {
  759.                 if (and( search_flags, SEARCH_FORWARD ))
  760.                     next_char( search_string_length )
  761.                 else
  762.                     prev_char( 1 )
  763.             }
  764.             if (ch == "" || ch == "") {
  765.                 warning("INTERRUPTED!")
  766.                 return
  767.             }
  768. #            search_flags = set_flag_bits( \
  769. #                    search_flags,
  770. #                    SEARCH_ADVANCE,
  771. #                    SEARCH_ADVANCE)
  772.         }
  773.         restore_position( TRUE )
  774.         if ( search_is_local() ) {
  775.             if (local_offset == end_offset) {
  776.                 swap_marks()
  777.                 restore_position()
  778.             }
  779.         }
  780.     } else {
  781.         if (search( serStr, search_flags )) {
  782.             next_char( search_string_length )
  783.             drop_anchor()
  784.             prev_char( search_string_length )
  785.             display_update()
  786.             found_replacement = TRUE
  787.             ch = tolower(confirm("Replace? (Y/N) ","YyNn"))
  788.             raise_anchor()
  789.             if (ch == "y") {
  790.                 _replace_current_item(serStr, replStr, search_flags)
  791.                 change_count++
  792.             } else if (ch == "" || ch == "") {
  793.                 warning("INTERRUPTED!")
  794.                 return
  795.             }
  796.         }
  797.     }
  798.     if (found_replacement == TRUE) {
  799.         message(sprintf("Translation complete; %d occurrence%s changed.",\
  800.         change_count, \
  801.         change_count == 1 ? "" : "s"))
  802.     } else {
  803.         message("Pattern not found." )
  804.     }
  805.     search_count = 0;
  806.     return found_replacement
  807. }
  808.  
  809.  
  810. #----------- Supporting search and replace functions ------------#
  811.  
  812. local optionStr = "", searchStr = "", searched = TRUE
  813.  
  814. #        set_search_options()
  815. #
  816. #        This local function is the one that processes the search option 
  817. #        characters obtained by the ws_search_find() and 
  818. #        ws_search_replace() functions.  Valid options include B)ackward 
  819. #        G)lobal, L)ocal, N)o-prompt, R)eg-ex and U)pper/lower-case.  The R 
  820. #        option is not standard to WordStar.
  821.  
  822. local function set_search_options(options) {
  823.     if ( options ~ /[^bglnru]/ ) {
  824.         return FALSE
  825.     }
  826.  
  827.     search_count = (options ~ /g/)        \
  828.             ? SEARCH_GLOBALLY    \
  829.             : 0
  830.  
  831.     # search_flags = (options ~ /g/)    \
  832.     # or(search_flags,SEARCH_ADVANCE)
  833.     # and(search_flags,not(SEARCH_ADVANCE))
  834.  
  835.     search_flags = (options ~ /u/)        \
  836.             ? or(search_flags,SEARCH_IGNORE_CASE)    \
  837.             : and(search_flags,not(SEARCH_IGNORE_CASE))
  838.  
  839.     search_prompt = (options ~ /n/)        \
  840.             ? FALSE            \
  841.             : TRUE
  842.  
  843.     search_flags = (options ~ /r/)        \
  844.             ? or(search_flags,SEARCH_REGEX)    \
  845.             : and(search_flags,not(SEARCH_REGEX))
  846.  
  847.     search_flags = (options ~ /b/)        \
  848.             ? and(search_flags,not(SEARCH_FORWARD))    \
  849.             : or(search_flags,SEARCH_FORWARD)
  850.  
  851.     search_flags = (options ~ /l/)        \
  852.             ? or(search_flags,SEARCH_BLOCK)    \
  853.             : and(search_flags,not(SEARCH_BLOCK))
  854.  
  855.     return TRUE
  856. }
  857.  
  858.  
  859. #        ws_search_find()
  860. #
  861. #        This function does searching WordStar style.  It prompts for a 
  862. #        search string and then prompts for option characters.
  863.  
  864. function ws_search_find() {
  865.     searched = TRUE
  866.     searchStr = prompt_history("SEARCH","Find:  ",searchStr)
  867.     if (searchStr !~ // && searchStr != "" && and(current_key,0x00FF) != 0x1b) {
  868.         optionStr = tolower(prompt("Options:  ",optionStr))
  869.         if (optionStr !~ // && and(current_key,0x00FF) != 0x1b)
  870.             if (set_search_options(optionStr)) {
  871.                 message("Searching...")
  872.                 if (!search(searchStr,search_flags))
  873.                     warning("Pattern not found." )
  874.                 else
  875.                     message("Search completed.")
  876.             } else
  877.                 message("Unrecognized option string <" optionStr ">" )
  878.         else
  879.             warning("Interrupted!")
  880.     }
  881. }
  882.  
  883. local replacementStr = ""
  884.  
  885. #        ws_search_replace()
  886. #
  887. #        This function does search and replacement WordStar style.  It 
  888. #        prompts for search and replacement strings and then option 
  889. #        characters.  It uses the prompt history mechanism to allow 
  890. #        previous responses to be recalled with the up arrow.
  891.  
  892. function ws_search_replace() {
  893.     searched = FALSE
  894.     searchStr = prompt_history("SEARCH","Find:  ",searchStr)
  895.     if (searchStr !~ // && searchStr != "") {
  896.         replacementStr = prompt_history("REPLACE","Replace with:  ",replacementStr)
  897.         if (replacementStr !~ // && and(current_key,0x00FF) != 0x1b) {
  898.             optionStr = tolower(prompt("Options:  ",optionStr))
  899.  
  900.             if (optionStr !~ // && and(current_key,0x00FF) != 0x1b)
  901.  
  902.             if (set_search_options(optionStr)) {
  903.                 ws_replacing(searchStr,replacementStr)
  904.             } else
  905.                 warning("Unrecognized option string <" optionStr ">" )
  906.         }
  907.     }
  908. }
  909.  
  910. #        ws_search_again()
  911. #
  912. #        This function repeats a search using the same parameters 
  913. #        previously specified.  If a block has been marked, the function 
  914. #        searches for the text found in the marked block.
  915.  
  916. function ws_search_again() {
  917.     local    direction, local_offset, end_offset
  918.  
  919.     if ( region_type() ) {
  920.         local_offset = buffer_offset
  921.         swap_marks()
  922.         if (local_offset < buffer_offset) {
  923.             local_offset = buffer_offset
  924.             swap_marks()
  925.         }
  926.         searchStr = read_buffer(local_offset - buffer_offset)
  927.         raise_anchor()
  928.     }
  929.     if (searchStr) {
  930.         direction = (and(search_flags,SEARCH_FORWARD)) ? 1 : -1
  931.         if (searched) {
  932.             if (next_char(direction) && search(searchStr,search_flags)) {
  933.                 message( "Search completed." )
  934.                 setSearchPos()
  935.             } else {
  936.                 warning("Pattern not found." )
  937.                 prev_char(direction)
  938.             }
  939.         } else {
  940.             if (next_char(direction) && ws_replacing(searchStr,replacementStr)) {
  941.                 warning( "Search completed." )
  942.                 setSearchPos()
  943.             } else {
  944.                 warning("Pattern not found." )
  945.                 prev_char(direction)
  946.             }
  947.         }
  948.     } else {
  949.         beep()
  950.         warning("No previous search pattern.")
  951.     }
  952. }
  953.  
  954. #        setSearchPos()
  955. #
  956. #        This function remembers the current position for restoration 
  957. #        later.  It is primarily used when doing multiple replaces.
  958.  
  959. local function setSearchPos() {
  960.     search_line    = current_line
  961.     search_column    = current_column
  962. }
  963.  
  964.  
  965. #        ws_restore()
  966. #
  967. #        This function restores various changes that this emulation makes 
  968. #        in the event that the user invokes another emulation.
  969.  
  970. function ws_restore(){
  971.     mouse_selection_type = previous_mst
  972.     delete_event(EVENT_EMULATION_CHANGED,function_id("ws_restore"))
  973. }
  974.