home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / ISPF.PEL < prev    next >
Text File  |  1995-04-20  |  91KB  |  3,120 lines

  1. # $Header:   P:\source\wmacros\ispf.pev   1.111   20 Apr 1995 11:02:54   pfhmlw0  $
  2.   
  3. ##############################################################################
  4. #
  5. #       Compuware Corporation
  6. #         31440 Northwestern Highway
  7. #           Farmington Hills, Michigan 48334-2564
  8. #
  9. #   This source code listing contains information that is
  10. #   proprietary to Compuware Corporation and may not be copied
  11. #   duplicated, translated, transmitted, stored, retrieved
  12. #   or in any manner or by any method conveyed or disclosed
  13. #   to a third party or parties without express written
  14. #   permission from Compuware Corporation.
  15. #
  16. #  
  17. ##############################################################################
  18.  
  19. #### $Workfile:   ispf.pel  $: Key bindings for ISPF compatibility
  20.  
  21. global ispf_cr_mode     = 0  # OFF = ISPF style cr mode flag (CR does not insert)
  22. global ispf_tab_mode    = 1  # ON  = ISPF style tab mode flag (Switch lc <-> data)
  23. global ispf_motion_mode = 1  # ON  = ISPF style home & end flag (no move past edge)
  24. global ispf_enter_mode  = 1  # 0 = <Enter> is Enter    1 = <Enter> is New-Line
  25. global ispf_home_mode   = 1  # 1 = <Home>  is command, 0 = <Home>  is home
  26.                              #     <Num-5> is home         <Num-5> is command
  27.  
  28. global ispf_scroll_amt  = "CSR"  # Default scroll amount
  29. global ispf_autosave    = FALSE  # ISPF's AUTOSAVE State
  30.  
  31. local  ispf_primary              # Table of ISPF Primary Commands -> PEL Functions
  32. global ispf_keymap      = -1     # The ISPF keymap!
  33.  
  34. global ispf_caps_mode   = 0      # TRUE = CAPS ON
  35. local  ispf_te_mode     = FALSE  # TRUE = Text Entry Mode.
  36. local  ispf_aid_func    = ""     # Function to call for AID keys.
  37.  
  38. global ispf_undo_size   = 30     # Max number of entries in ispf_undo_stack
  39. local  ispf_undo_stack           # stack of undo_index's for each buffer
  40. local  ispf_undo_index           # pointer to current entry in ispf_undo_stack
  41. local  ispf_last_index           # pointer to last entry in ispf_undo_stack
  42.  
  43. global error_mark                # string to mark errors with.
  44.  
  45. local  rfind_failed     = 0      # TRUE = last RFIND or RCHANGE failed
  46. local  rfind_key        = 0      # TRUE = perform RFIND instead of CHANGE
  47.  
  48. #
  49. # Flags used by ispf_parse_find to return search state
  50. #
  51. global ispf_default = 0         # Default starting values for ispf_flags
  52.  
  53. local  ispf_flags
  54. local  ISPF_DIRS    = 0x0003F   # Mask for Direction Flags
  55. local  ISPF_ALL     = 0x00001
  56. local  ISPF_NEXT    = 0x00002
  57. local  ISPF_PREV    = 0x00004
  58. local  ISPF_FIRST   = 0x00008
  59. local  ISPF_LAST    = 0x00010
  60. local  ISPF_PROMPT  = 0x00020
  61.  
  62. local  ISPF_PARMS   = 0x00700   # Mask for Parameter Flags
  63. local  ISPF_CHARS   = 0x00100
  64. local  ISPF_PREFIX  = 0x00200
  65. local  ISPF_SUFFIX  = 0x00400
  66. local  ISPF_WORD    = 0x00800
  67.  
  68. local  ISPF_EXCLUDE = 0x000C0   # Mask for Exclude Flags
  69. local  ISPF_X       = 0x00040   # (Not currently used)
  70. local  ISPF_NX      = 0x00080   # (Not currently used)
  71.  
  72. local  ISPF_ICASE   = 0x01000   # Ignore Case
  73. local  ISPF_REGEX   = 0x02000   # Use regular experessions
  74. local  ISPF_BLOCK   = 0x04000   # Perform a block Find/Change
  75.  
  76. local  ISPF_ERROR   = 0x08000   # Set by ispf_parse_find for errors
  77.  
  78. local old_linenumber_format
  79. local insert_on 
  80. #
  81. # ISPF Emulation Functions
  82. #
  83. global function ISPF()
  84. {
  85.    ispf()
  86. }
  87.  
  88. # read the ispf settings the first time ispf is selected
  89. local read_ispf_settings = 1
  90.  
  91. global function ispf()
  92. {
  93.    local prevPauseOnError
  94.  
  95.    if (read_ispf_settings)
  96.    {
  97.       read_ispf_settings = 0
  98.       read_config_section("$ISPF$")
  99.    }
  100.  
  101.    if (emulation_mode != "ispf")
  102.    {
  103.       emulation_mode = "ispf"
  104.       execute_event_handler( EVENT.EMULATION_CHANGED )
  105.  
  106.       # hook our exit routine BEFORE the standard one!
  107.       delete_event(EVENT.EXIT_EDITOR,         "exit_editor")
  108.       attach_event_handler(EVENT.EXIT_EDITOR, "ispf_quit")
  109.       attach_event_handler(EVENT.EXIT_EDITOR, "exit_editor")
  110.  
  111.       attach_event_handler(EVENT.NEW_EDIT_FILE,     "ispf_new_file")
  112.       attach_event_handler(EVENT.NEW_EMPTY_BUFFER,  "ispf_empty_file")
  113.       attach_event_handler(EVENT.EMULATION_CHANGED, "ispf_exit")
  114.       attach_event_handler(EVENT.MENU_COMMAND,      "ispexec")
  115.  
  116.       # pause if an error or warning occurs during initialization
  117.       prevPauseOnError = pause_on_error
  118.       pause_on_error   = 1
  119.  
  120.       # set up ispf menu and keymap
  121.       create_ispf_keymap()
  122.       ispf_menu()
  123.  
  124.       # Set the message level to all messages.
  125.       message_level                 = 0
  126.  
  127.       # Turn on extended_quotes for find & change.
  128.       extended_quotes               = TRUE
  129.  
  130.       # set up the find, error and change marks for global searches
  131.       find_mark                     = "==FND>"
  132.       error_mark                    = "==ERR>"
  133.       change_mark                   = "==CHG>"
  134.  
  135.       # setup some default window values
  136.       default_scroll_context_top    = 0
  137.       default_scroll_context_bottom = 0
  138.       default_scroll_context_right  = 0
  139.       default_scroll_context_left   = 0
  140.       default_visible_end_buffer    = strrepeat("=", 33) "BOTTOM OF DATA" \
  141.                                       strrepeat("=", 175)
  142.  
  143.       # set up default search characteristics
  144.       search_flags = SEARCH_MAXIMAL_MATCH                  \
  145.                    + SEARCH_FORWARD                        \
  146.                    + SEARCH_BLOCK                          \
  147.                    + SEARCH_HIGHLIGHT                      \
  148.                    + SEARCH_MARK_CHG                       \
  149.                    + SEARCH_WRAPS                          \
  150.       #            + SEARCH_REGEX                          \
  151.  
  152.       # misc defaults
  153.       insert_on = !and(buffer_flags, BUFFER_OVERTYPE_MODE)
  154.       toggle_buffer_flags(BUFFER_OVERTYPE_MODE, 0 )
  155.  
  156.       pause_on_error        = prevPauseOnError
  157.       old_linenumber_format = linenumber_format
  158.    }
  159.  
  160.    # Always turn on line commands and numbers
  161.    toggle_linecommands( 1 )
  162.    linecommands_enabled      = 1
  163.    default_linenumber_format = nominal_linenumber_format
  164.  
  165.    setup_windows()
  166.    setup_buffers()
  167. }
  168.  
  169. global function setup_buffers()
  170. {
  171.    if (current_buffer && buffer_size == 0)
  172.       execute_event_handler(EVENT.NEW_EMPTY_BUFFER)
  173. }
  174.  
  175. global function setup_windows()
  176. {
  177.    local start_window
  178.  
  179.    if (current_window)
  180.    {
  181.       start_window = current_window
  182.       do
  183.       {
  184.          linenumber_format      = default_linenumber_format
  185.          visible_end_buffer     = default_visible_end_buffer
  186.          visible_newlines       = default_visible_newlines
  187.          visible_spaces         = default_visible_spaces
  188.          visible_tabs           = default_visible_tabs
  189.          visible_virtual_lines  = default_visible_virtual_lines
  190.          visible_virtual_spaces = default_visible_virtual_spaces
  191.  
  192.          scroll_context_top     = default_scroll_context_top
  193.          scroll_context_bottom  = default_scroll_context_bottom
  194.          scroll_context_right   = default_scroll_context_right
  195.          scroll_context_left    = default_scroll_context_left
  196.       } while (next_window() != start_window)
  197.    }
  198. }
  199.  
  200. # this function is used to customize the menu so that the keys you have
  201. # assigned to do the same thing as the menuitem will show on the menu
  202. # It should be global and start with the string inside emulation_mode
  203. function ispf_menu()
  204. {
  205.    local menu = menu_info(0, MI_MENUHANDLE);
  206.    
  207.    cua_menu(1) # Start with CUA's menu with No FKeys!
  208.  
  209.    # Alter ISPF Specific Menuitems.
  210.  
  211.    if ( menu )
  212.    {
  213.       modify_menuitem( menu,   IDM_CLOSE,     MI_KEYSTEXT, "PF3")
  214.       modify_menuitem( menu,   IDM_EXIT,      MI_KEYSTEXT, "PF4")
  215.       modify_menuitem( menu,   IDM_FINDAGAIN, MI_KEYSTEXT, "PF5")
  216.       
  217.       modify_menuitem( menu,   IDM_ADDFILE,   MI_KEYSTEXT, "Ctrl-O")
  218.       modify_menuitem( menu,   IDM_NEXT,      MI_KEYSTEXT, "Ctrl-N")
  219.  
  220.       menu_functions[IDM_COMMAND] = "ispf_command"
  221.    }
  222.    ispf_alter_menu()
  223. }
  224.  
  225. local function ispf_alter_menu()
  226. {
  227.    local menu = menu_info(0, MI_MENUHANDLE);
  228.  
  229.    if ( menu )
  230.    {
  231.       if (ispf_home_mode)
  232.          modify_menuitem( menu,  IDM_COMMAND, MI_KEYSTEXT, "Home")
  233.       else
  234.          modify_menuitem( menu,  IDM_COMMAND, MI_KEYSTEXT, "Num-5")
  235.    }
  236. }
  237.  
  238. local function ispf_fix_menu()
  239. {
  240.    menu_functions[IDM_COMMAND] = "gui_command"
  241. }
  242.  
  243. global function create_ispf_keymap()
  244. {
  245.    # Enable the keymap.  Subsequent mods to the keymap will persist
  246.    #       through the end of the session.
  247.    # Only one-time initialization should follow this point.
  248.    
  249.    if ( ispf_keymap >= 0 )
  250.    {
  251.       current_keymap = ispf_keymap
  252.       return
  253.    }
  254.    else
  255.    {
  256.       current_keymap = ispf_keymap = create_keymap( ascii_keymap )
  257.    
  258.       assign_ispf_keys()
  259.       assign_ispf_line_commands()
  260.       assign_ispf_primary_commands()
  261. #     assign_mouse_buttons()
  262.       optional_function("local_keys")
  263.    }
  264. }
  265.  
  266. global function assign_ispf_keys()
  267. {
  268.    #--------------------------------------------------------------
  269.    # Function Key bindings (F1-F12)
  270.    #--------------------------------------------------------------
  271. #  assign_key( "<F1>",                     "isrexec HELP" )
  272.    assign_key( "<F2>",                     "isrexec SPLIT" )
  273.    assign_key( "<F3>",                     "isrexec END" )
  274.    assign_key( "<F4>",                     "isrexec RETURN" )
  275.    assign_key( "<F5>",                     "isrexec RFIND" )
  276.    assign_key( "<F6>",                     "isrexec RCHANGE" )
  277.    assign_key( "<F7>",                     "isrexec UP" )
  278.    assign_key( "<F8>",                     "isrexec DOWN" )
  279.    assign_key( "<F9>",                     "isrexec SWAP" )
  280.    assign_key( "<F10>",                    "isrexec LEFT" )
  281.    assign_key( "<F11>",                    "isrexec RIGHT" )
  282.    assign_key( "<F12>",                    "isrexec RETRIEVE" )
  283.  
  284.    #--------------------------------------------------------------
  285.    # Function Key bindings (F12-F24)
  286.    #--------------------------------------------------------------
  287. #  assign_key( "<Shift-F1>",               "isrexec HELP" )
  288.    assign_key( "<Shift-F2>",               "isrexec SPLIT" )
  289.    assign_key( "<Shift-F3>",               "isrexec END" )
  290.    assign_key( "<Shift-F4>",               "isrexec RETURN" )
  291.    assign_key( "<Shift-F5>",               "isrexec RFIND" )
  292.    assign_key( "<Shift-F6>",               "isrexec RCHANGE" )
  293.    assign_key( "<Shift-F7>",               "isrexec UP" )
  294.    assign_key( "<Shift-F8>",               "isrexec DOWN" )
  295.    assign_key( "<Shift-F9>",               "isrexec SWAP" )
  296.    assign_key( "<Shift-F10>",              "isrexec LEFT" )
  297.    assign_key( "<Shift-F11>",              "isrexec RIGHT" )
  298.    assign_key( "<Shift-F12>",              "isrexec RETRIEVE" )
  299.  
  300.    #--------------------------------------------------------------
  301.    # Define Alt-# Keys to emulate 3270 Terminal Emulators (IRMA).
  302.    #--------------------------------------------------------------
  303. #  assign_key( "<Alt-1>",                  "isrexec HELP" )
  304.    assign_key( "<Alt-2>",                  "isrexec SPLIT" )
  305.    assign_key( "<Alt-3>",                  "isrexec END" )
  306.    assign_key( "<Alt-4>",                  "isrexec RETURN" )
  307.    assign_key( "<Alt-5>",                  "isrexec RFIND" )
  308.    assign_key( "<Alt-6>",                  "isrexec RCHANGE" )
  309.    assign_key( "<Alt-7>",                  "isrexec UP" )
  310.    assign_key( "<Alt-8>",                  "isrexec DOWN" )
  311.    assign_key( "<Alt-9>",                  "isrexec SWAP" )
  312.    assign_key( "<Alt-0>",                  "isrexec LEFT" )
  313.    assign_key( "<Alt-->",                  "isrexec RIGHT" )
  314.    assign_key( "<Alt-=>",                  "isrexec RETRIEVE" )
  315.  
  316.    #--------------------------------------------------------------
  317.    # Define Ctrl-# Keys to emulate 3270 Terminal Emulators (IRMA).
  318.    #--------------------------------------------------------------
  319. #  assign_key( "<Ctrl-1>",                 "isrexec HELP" )
  320.    assign_key( "<Ctrl-2>",                 "isrexec SPLIT" )
  321.    assign_key( "<Ctrl-3>",                 "isrexec END" )
  322.    assign_key( "<Ctrl-4>",                 "isrexec RETURN" )
  323.    assign_key( "<Ctrl-5>",                 "isrexec RFIND" )
  324.    assign_key( "<Ctrl-6>",                 "isrexec RCHANGE" )
  325.    assign_key( "<Ctrl-7>",                 "isrexec UP" )
  326.    assign_key( "<Ctrl-8>",                 "isrexec DOWN" )
  327.    assign_key( "<Ctrl-9>",                 "isrexec SWAP" )
  328.    assign_key( "<Ctrl-0>",                 "isrexec LEFT" )
  329.    assign_key( "<Ctrl-->",                 "isrexec RIGHT" )
  330.    assign_key( "<Ctrl-=>",                 "isrexec RETRIEVE" )
  331.  
  332.    #--------------------------------------------------------------
  333.    # Ctrl + Alt key combinations on the main keyboard:
  334.    #--------------------------------------------------------------
  335.  
  336.    #--------------------------------------------------------------
  337.    # Menu 
  338.    #--------------------------------------------------------------
  339.    assign_key( "<Esc>",                    "expand_template")
  340.    assign_key( "<Ctrl-F1>",                "display_help_item")
  341.    assign_key( "<Ctrl-H>",                 "display_help_item")
  342.  
  343.    #--------------------------------------------------------------
  344.    # Cursor Movement
  345.    #--------------------------------------------------------------
  346.    assign_key( "<Ctrl-G>",                 "ispexec goto_line_key" )
  347.    
  348.    #--------------------------------------------------------------
  349.    # Marked Blocks
  350.    #--------------------------------------------------------------
  351.    assign_key( "<Ctrl-M>",                 "set_inclusive_mark" )
  352.    assign_key( "<Ctrl-L>",                 "set_line_mark" )
  353.    assign_key( "<Ctrl-C>",                 "set_column_mark" )
  354.    assign_key( "<Ctrl-E>",                 "set_exclusive_mark" ) # Ctrl-A
  355.  
  356.    #--------------------------------------------------------------
  357.    # Command Dialog
  358.    #--------------------------------------------------------------
  359.    assign_key( "<Ctrl-A>",                 "ispf_command" )
  360.  
  361.    #--------------------------------------------------------------
  362.    # Basic Text commands
  363.    #--------------------------------------------------------------
  364.    assign_key( "<Ctrl-D>",                 "delete_line" )
  365.    assign_key( "<Ctrl-K>",                 "delete_to_eol" )
  366.  
  367.    #--------------------------------------------------------------
  368.    # Manipulating Buffers
  369.    #--------------------------------------------------------------
  370.    assign_key( "<Ctrl-O>",                 "ispexec gui_open" )
  371.    assign_key( "<Ctrl-R>",                 "ispexec gui_insert_file" )
  372.    assign_key( "<Ctrl-W>",                 "ispexec write_block_or_buffer_key" )
  373.    assign_key( "<Ctrl-N>",                 "ispexec next_buffer_mask" )
  374.    assign_key( "<Ctrl-Shift-N>",           "ispexec prev_buffer_mask" )
  375.    assign_key( "<Ctrl-B>",                 "ispexec buffer_list" )
  376.    assign_key( "<Ctrl-X>",                 "ispexec write_and_exit" )
  377.  
  378.    #--------------------------------------------------------------
  379.    # Searching and translating
  380.    #--------------------------------------------------------------
  381.    assign_key( "<Ctrl-S>",                 "ispexec gui_find" )
  382.    assign_key( "<Ctrl-Shift-S>",           "ispexec gui_find" )
  383.    assign_key( "<Ctrl-F>",                 "ispexec search_again" )
  384.    assign_key( "<Ctrl-T>",                 "ispexec gui_change" )
  385.    assign_key( "<Ctrl-Shift-T>",           "ispexec gui_change" )
  386.    assign_key( "<Alt-Shift-S>",   function_id("toggle_search_flags", SEARCH_CASE) )
  387.    assign_key( "<Alt-Shift-R>",   function_id("toggle_search_flags", SEARCH_REGEX) )
  388.  
  389.    #--------------------------------------------------------------
  390.    # Bookmarks
  391.    #--------------------------------------------------------------
  392.    assign_key( "<Ctrl-J>",                 "ispexec goto_bookmark" )
  393.  
  394.    #--------------------------------------------------------------
  395.    # Miscellaneous
  396.    #--------------------------------------------------------------
  397.    assign_key( "<Alt-W>",                  "gui_save" )
  398.    assign_key( "<Alt-X>",                  "ispexec done" )
  399.    assign_key( "<Ctrl-V>",                 "print_version" )
  400.    assign_key( "<Ctrl-Q>",                 "insert_quoted_key" )
  401.  
  402.    #--------------------------------------------------------------
  403.    # Numpad keys, keypad keys & non-ASCII keys on main keyboard:
  404.    #--------------------------------------------------------------
  405.  
  406.    #--------------------------------------------------------------
  407.    # ISPF specific Definitions
  408.    #--------------------------------------------------------------
  409.    assign_key( "<Tab>",                    "ispf_tab" )
  410.  
  411.    # use BackTab for OS2 and Shift-Tab for windows
  412.    assign_key( "<BackTab>",                "ispf_backtab" )
  413.  
  414.    assign_key( "<Enter>",                  "ispf_return" )
  415.    assign_key( "<Ctrl-Enter>",             "ispf_enter" )
  416.  
  417.    assign_key( "<Num-Enter>",              "ispf_execute" )
  418.    assign_key( "<Ctrl>",                   "ispf_execute" )
  419.  
  420.    assign_key( "<Space>",                  "insert_key" )
  421.    assign_key( "<Backspace>",              "backspace" )
  422.  
  423.    assign_key( "<Home>",                   "ispf_home_key" )
  424.    assign_key( "<Num-5>",                  "ispf_center_key" )
  425.    assign_key( "<End>",                    "ispf_end_key" )
  426.  
  427.    assign_key( "<Alt-Left>",               "left 2" )
  428.    assign_key( "<Alt-Right>",              "right 2" )
  429.    assign_key( "<Alt-Down>",               "down 2" )
  430.    assign_key( "<Alt-Up>",                 "up 2" )
  431.  
  432.    #--------------------------------------------------------------
  433.    # Copy of CUA Definitions since ISPF does not define any of
  434.    # these actions itself.
  435.    #--------------------------------------------------------------
  436.  
  437.    #--------------------------------------------------------------
  438.    # Cursor Movement
  439.    #--------------------------------------------------------------
  440.    assign_key( "<Left>",                   "left" )                     #CUA
  441.    assign_key( "<Right>",                  "right" )                    #CUA
  442.    assign_key( "<Down>",                   "down" )                     #CUA
  443.    assign_key( "<Up>",                     "up" )                       #CUA
  444.    assign_key( "<PageDown>",               "isrexec DOWN" )             #CUA
  445.    assign_key( "<PageUp>",                 "isrexec UP" )               #CUA
  446.    
  447.    assign_key( "<Alt-F4>",                 "done2" )                #CUA
  448.  
  449.    assign_key( "<Ctrl-Left>",              "prev_word" )                #CUA
  450.    assign_key( "<Ctrl-Right>",             "next_word" )                #CUA
  451.    assign_key( "<Ctrl-Down>",              "down_whitespace" )
  452.    assign_key( "<Ctrl-Up>",                "up_whitespace" )
  453.    assign_key( "<Ctrl-Home>",              "goto_bol" )
  454.    assign_key( "<Ctrl-End>",               "goto_eol" )
  455.    assign_key( "<Ctrl-PageDown>",          "ispexec goto_buffer_bottom" )
  456.    assign_key( "<Ctrl-PageUp>",            "ispexec goto_buffer_top" )
  457.    
  458.    assign_key( "<Ctrl-Num-Left>",          "prev_word" )                #CUA
  459.    assign_key( "<Ctrl-Num-Right>",         "next_word" )                #CUA
  460.    assign_key( "<Ctrl-Num-Down>",          "down_whitespace" )
  461.    assign_key( "<Ctrl-Num-Up>",            "up_whitespace" )
  462.    assign_key( "<Ctrl-Num-Home>",          "goto_bol" )
  463.    assign_key( "<Ctrl-Num-End>",           "goto_eol" )
  464.    assign_key( "<Ctrl-Num-PageDown>",      "ispexec goto_buffer_bottom" )
  465.    assign_key( "<Ctrl-Num-PageUp>",        "ispexec goto_buffer_top" )
  466.    
  467.    #--------------------------------------------------------------
  468.    # Marked Blocks
  469.    #--------------------------------------------------------------
  470.    assign_key( "<Shift-Delete>",           "gui_delete_to_scrap" )      #CUA
  471.    assign_key( "<Shift-Insert>",           "ispexec insert_scrap" )     #CUA
  472.    assign_key( "<Ctrl-Insert>",            "copy_to_scrap_key" )        #CUA
  473.    assign_key( "<Ctrl-Delete>",            "delete_to_eol" )
  474.    assign_key( "<Num-->",                  "gui_delete_to_scrap" )
  475.    assign_key( "<Num-+>",                  "copy_to_scrap_key" )
  476.  
  477.    assign_key( "<Shift-Left>",             "cua_extend" )               #CUA
  478.    assign_key( "<Shift-Right>",            "cua_extend" )               #CUA
  479.    assign_key( "<Shift-Down>",             "cua_extend" )               #CUA
  480.    assign_key( "<Shift-Up>",               "cua_extend" )               #CUA
  481.  
  482.    assign_key( "<Shift-Home>",             "cua_extend" )               #CUA
  483.    assign_key( "<Shift-End>",              "cua_extend" )               #CUA
  484.    assign_key( "<Shift-PageDown>",         "cua_extend" )               #CUA
  485.    assign_key( "<Shift-PageUp>",           "cua_extend" )               #CUA
  486.    
  487.    assign_key( "<Ctrl-Shift-Left>",        "cua_extend" )               #CUA
  488.    assign_key( "<Ctrl-Shift-Right>",       "cua_extend" )               #CUA
  489.    assign_key( "<Ctrl-Shift-Down>",        "cua_extend" )
  490.    assign_key( "<Ctrl-Shift-Up>",          "cua_extend" )
  491.    assign_key( "<Ctrl-Shift-Home>",        "cua_extend" )               #CUA
  492.    assign_key( "<Ctrl-Shift-End>",         "cua_extend" )               #CUA
  493.    assign_key( "<Ctrl-Shift-PageDown>",    "cua_extend" )               #CUA
  494.    assign_key( "<Ctrl-Shift-PageUp>",      "cua_extend" )               #CUA
  495.  
  496.    #--------------------------------------------------------------
  497.    # Basic Text commands
  498.    #--------------------------------------------------------------
  499.    assign_key( "<Delete>",                 "delete_chars" )             #CUA
  500.    assign_key( "<Insert>",     function_id("toggle_buffer_flags", BUFFER_OVERTYPE_MODE) )       #CUA
  501.  
  502.    assign_key( "<Ctrl-Backspace>",         "delete_prev_word" )
  503.    assign_key( "<Shift-Backspace>",        "delete_word" )
  504.  
  505.    #--------------------------------------------------------------
  506.    # Undo / Redo
  507.    #--------------------------------------------------------------
  508.    assign_key( "<Alt-Backspace>",          "undo" )                     #CUA
  509.    assign_key( "<Alt-Shift-Backspace>",    "redo" )
  510.    
  511.    #--------------------------------------------------------------
  512.    # Commands borrowed from Brief
  513.    #--------------------------------------------------------------
  514.    assign_key( "<Num-*>",                  "undo" )
  515.    assign_key( "<Num-/>",                  "redo" )
  516.    assign_key( "<Alt-Num-->",              "ispexec prev_buffer_mask" )
  517.    assign_key( "<Ctrl-Num-->",             "ispexec brief_delete_buffer" )
  518. }
  519.  
  520. global function assign_ispf_line_commands()
  521. {
  522.    delete_lc()
  523.  
  524.    assign_transfer("C",     "copy_to_dest")  # Setup transfer commands
  525.    assign_transfer("CC",    "copy_to_dest")
  526.    assign_transfer("M",     "move_to_dest")
  527.    assign_transfer("MM",    "move_to_dest")
  528.    assign_transfer(".line", "copy_to_dest")
  529.  
  530.    assign_lc(".label",   "validate_label")   # Setup special commands
  531.    assign_lc(".insert",  "cleanup_insert")
  532.    assign_lc("=flag",    "")
  533.  
  534.    assign_lc("C",        "mark_1_line")      # Setup source commands
  535.    assign_lc("CC",       "mark_lines")
  536.    assign_lc("M",        "mark_1_line")
  537.    assign_lc("MM",       "mark_lines")
  538.  
  539.    assign_lc("B",        "transfer_lines B") # Setup destination commands
  540.    assign_lc("A",        "transfer_lines A")
  541.  
  542.    assign_lc("I",        "insert_lines")     # Setup the rest of the commands
  543.  
  544.    assign_lc("TE",       "ispf_text_entry")
  545.    assign_lc("TS",       "ispf_text_split")
  546.    assign_lc("TJ",       "ispf_text_join")
  547.  
  548.    assign_lc("R",        "repeat_lines")
  549.    assign_lc("RR",       "mark_lines repeat_lines")
  550.  
  551.    assign_lc("D",        "delete_lines")
  552.    assign_lc("DD",       "mark_lines delete_lines")
  553.  
  554.    assign_lc("S",        "select_lines")            # CPE Extension to ISPF
  555.    assign_lc("SS",       "mark_lines select_lines")
  556.  
  557.    assign_lc("LC",       "lcase_lines")
  558.    assign_lc("LCC",      "mark_lines lcase_lines")
  559.    assign_lc("LCLC",     "mark_lines lcase_lines")
  560.  
  561.    assign_lc("UC",       "ucase_lines")
  562.    assign_lc("UCC",      "mark_lines ucase_lines")
  563.    assign_lc("UCUC",     "mark_lines ucase_lines")
  564.  
  565.    assign_lc("(",        "lshift_cols")
  566.    assign_lc("((",       "mark_lines lshift_cols")
  567.    assign_lc(")",        "rshift_cols")
  568.    assign_lc("))",       "mark_lines rshift_cols")
  569.  
  570.    assign_lc("<",        "lshift_data")
  571.    assign_lc("<<",       "mark_lines lshift_data")
  572.    assign_lc(">",        "rshift_data")
  573.    assign_lc(">>",       "mark_lines rshift_data")
  574.  
  575.    assign_lc("TF",       "ispf_nyi")
  576.  
  577.    assign_lc("O",        "ispf_nyi")
  578.    assign_lc("OO",       "ispf_nyi")
  579.  
  580.    assign_lc("X",        "ispf_nyi")
  581.    assign_lc("XX",       "ispf_nyi")
  582. }
  583.  
  584. global function assign_ispf_primary_commands()
  585. {
  586.    ispf_primary["HELP"]     = "display_help_item"
  587.    ispf_primary["FSPLIT"]   = "ispf_fsplit"
  588.    ispf_primary["SPLIT"]    = "ispf_split"
  589.    ispf_primary["SWAP"]     = "ispf_swap"
  590.    ispf_primary["RETRIEVE"] = "ispf_command 1"
  591.  
  592.    ispf_primary["FIND"]     = "ispf_find"
  593.    ispf_primary["F"]        = "ispf_find"
  594.  
  595.    ispf_primary["CHANGE"]   = "ispf_change"
  596.    ispf_primary["CHG"]      = "ispf_change"
  597.    ispf_primary["C"]        = "ispf_change"
  598.  
  599.    ispf_primary["RFIND"]    = "ispf_rfind"
  600.    ispf_primary["RCHANGE"]  = "ispf_rchange"
  601.  
  602.    ispf_primary["RIGHT"]    = "ispf_right"
  603.    ispf_primary["LEFT"]     = "ispf_left"
  604.  
  605.    ispf_primary["UP"]       = "ispf_up"
  606.    ispf_primary["U"]        = "ispf_up"
  607.  
  608.    ispf_primary["DOWN"]     = "ispf_down"
  609.    ispf_primary["D"]        = "ispf_down"
  610.  
  611.    ispf_primary["LOCATE"]   = "ispf_locate"
  612.    ispf_primary["LOC"]      = "ispf_locate"
  613.    ispf_primary["L"]        = "ispf_locate"
  614.  
  615.    ispf_primary["DELETE"]   = "ispf_delete"
  616.    ispf_primary["DEL"]      = "ispf_delete"
  617.  
  618.    ispf_primary["INSERT"]   = "islexec I"
  619.    ispf_primary["INS"]      = "islexec I"
  620.  
  621.    ispf_primary["TENTER"]   = "islexec TE"
  622.    ispf_primary["TE"]       = "islexec TE"
  623.  
  624.    ispf_primary["TJOIN"]    = "islexec TJ"
  625.    ispf_primary["TJ"]       = "islexec TJ"
  626.  
  627.    ispf_primary["TSPLIT"]   = "islexec TS"
  628.    ispf_primary["TS"]       = "islexec TS"
  629.  
  630.    ispf_primary["COPY"]     = "ispf_copy_file"
  631.    ispf_primary["MOVE"]     = "ispf_move_file"
  632.  
  633.    ispf_primary["CREATE"]   = "ispf_create_file"
  634.    ispf_primary["CRE"]      = "ispf_create_file"
  635.  
  636.    ispf_primary["REPLACE"]  = "ispf_replace_file"
  637.    ispf_primary["REPL"]     = "ispf_replace_file"
  638.    ispf_primary["REP"]      = "ispf_replace_file"
  639.  
  640.    ispf_primary["RESET"]    = "ispf_reset"
  641.    ispf_primary["RES"]      = "ispf_reset"
  642.  
  643.    ispf_primary["UNDO"]     = "ispf_undo"
  644.    ispf_primary["REDO"]     = "ispf_redo"
  645.  
  646.    ispf_primary["LABEL"]    = "ispf_label"
  647.  
  648.    ispf_primary["NEW"]      = "gui_new"              # CPE Extension to ISPF
  649.  
  650.    ispf_primary["EDIT"]     = "create_buf_and_win_key"
  651.    ispf_primary["E"]        = "create_buf_and_win_key"
  652.  
  653.    ispf_primary["BROWSE"]   = "browse_file"
  654.    ispf_primary["B"]        = "browse_file"
  655.  
  656.    ispf_primary["SAVE"]     = "write_buffer_key"
  657.    ispf_primary["SAV"]      = "write_buffer_key"
  658.    ispf_primary["S"]        = "write_buffer_key"
  659.  
  660.    ispf_primary["CANCEL"]   = "ispf_close 1 0"
  661.    ispf_primary["CAN"]      = "ispf_close 1 0"
  662.    ispf_primary["END"]      = "ispf_close 0 0"
  663.    ispf_primary["RETURN"]   = "ispf_close 0 1"
  664.    ispf_primary["=X"]       = "ispf_close 0 1"
  665.  
  666.    ispf_primary["CPE"]      = ""
  667.    ispf_primary["PEL"]      = ""
  668.    ispf_primary["DOS"]      = "system"
  669.    ispf_primary["OS2"]      = "system"
  670.    ispf_primary["TSO"]      = "system"
  671.  
  672.    ispf_primary["RECOVERY"] = "ispf_recovery"
  673.    ispf_primary["AUTOSAVE"] = "set_ispf_autosave"
  674.    ispf_primary["TABS"]     = "set_ispf_tabs"
  675.    ispf_primary["CAPS"]     = "set_ispf_caps"
  676.    ispf_primary["HEX"]      = "set_ispf_hex"
  677.  
  678.    ispf_primary["CUT"]      = "ispf_cut"
  679.    ispf_primary["PASTE"]    = "ispf_paste"
  680.  
  681.    ispf_primary["SHIFT"]    = "ispf_nyi"
  682.    ispf_primary["TFLOW"]    = "ispf_nyi"
  683.    ispf_primary["PRINT"]    = "ispf_nyi"
  684.  
  685.    # this is NOT what profile does in the "real" thing,
  686.    # but this should be an acceptable replacement.
  687.  
  688.    ispf_primary["PRO"]      = "create_ispf_page"
  689.    ispf_primary["PROFILE"]  = "create_ispf_page"
  690. }
  691.  
  692. #
  693. # Global function to process the ISPF Command Line
  694. #
  695. global function ispf_command(retrieve)
  696. {
  697.    local command
  698.    local ret
  699.    local fid     = function_id( "ispf_command_key" )
  700.  
  701.    rfind_key     = FALSE
  702.    lc_message    = ""
  703.    ispf_aid_func = ""
  704.  
  705.    #
  706.    # install an event handler to make command history
  707.    # available to the prompt function.
  708.    #
  709.    attach_event_handler( EVENT.INVALID_PCHAR, fid )
  710.  
  711.    if (retrieve)
  712.       command = prompt_history("ISPF", "COMMAND ===>", "", 1)
  713.    else
  714.       command = prompt_history("ISPF", "COMMAND ===>")
  715.  
  716.    #
  717.    # remove the prompt event handler
  718.    #
  719.    delete_event( EVENT.INVALID_PCHAR, fid )
  720.  
  721.    if (length(ispf_aid_func))
  722.       ret = invoke_function(ispf_aid_func " " command)
  723.    else if (length(command))
  724.       ret = isrexec(command)
  725.    else
  726.       ret = FALSE
  727.  
  728.    #
  729.    # update the message line.
  730.    #
  731.    show_message(FALSE)
  732.    return ret
  733. }
  734.  
  735. #
  736. # Event Handler for ISPF Command Prompt Keys.
  737. #
  738. global function ispf_command_key()
  739. {
  740.    local orig_key = current_key
  741.  
  742.    if ( current_key == key_to_int("<Ctrl>") )
  743.         current_key = KEYCODE_ENTER
  744.    else if ( current_key == key_to_int("<Ctrl-Enter>") )
  745.         current_key = KEYCODE_ENTER
  746.    else if ( in_binding(current_key, function_id("isrexec RETRIEVE")) )
  747.         current_key = KEYCODE_UP
  748.    else if ( in_binding(current_key, function_id("isrexec UP"))   ||
  749.              in_binding(current_key, function_id("isrexec DOWN")) ||
  750.              in_binding(current_key, function_id("isrexec LEFT")) ||
  751.              in_binding(current_key, function_id("isrexec RIGHT")) )
  752.    {
  753.       ispf_aid_func = keymap_binding(sprintf("#%d", current_key))
  754.       current_key   = KEYCODE_ENTER
  755.    }
  756.    else if ( in_binding(current_key, function_id("isrexec RFIND")) )
  757.    {
  758.       rfind_key   = TRUE
  759.       current_key = KEYCODE_ENTER
  760.    }
  761. }
  762.  
  763. #
  764. # Global function to add ISPF commands to the symbol_list
  765. #
  766. global function ispf_commands(searchFor)
  767. {
  768.    local i
  769.    searchFor = tolower(searchFor)
  770.    for (i in ispf_primary)
  771.    {
  772.       if (match(tolower(i), "^" searchFor ".*" ))
  773.          symbol_list[i] = i
  774.    }
  775. }
  776.  
  777. #
  778. # Global Function to determine if a keycode is mapped to a specific function
  779. #
  780. global function in_binding(key, fid, keymap)
  781. {
  782.    local keycode  = sprintf("#%d", key)
  783.    local bindings
  784.  
  785.    if (argcount() == 1 || !fid)
  786.    {
  787.       if (argcount() > 2 && keymap)
  788.         return length(keymap_binding(keycode, keymap)) > 0
  789.       else
  790.         return length(keymap_binding(keycode)) > 0
  791.    }
  792.    else
  793.    {
  794.       if (argcount() > 2 && keymap)
  795.          bindings = function_binding(fid, keymap)
  796.       else
  797.          bindings = function_binding(fid)
  798.  
  799.       return (index(bindings, keycode) > 0)
  800.    }
  801. }
  802.  
  803. #
  804. # Global function to process_command_lines before executing a function.
  805. #
  806. global function ispexec(cmd)
  807. {
  808.    local ret
  809.  
  810.    ispf_te_mode = FALSE # Reset TE Mode.
  811.    ispf_push_undo()
  812.  
  813.    if (process_line_commands() && argcount() && length(cmd))
  814.       ret = execute_function(cmd)
  815.    else
  816.    {
  817.       if (ispf_caps_mode)
  818.       {
  819.          set_line_mark()
  820.          upper()
  821.          remove_selection()
  822.       }
  823.       ret = FALSE
  824.    }
  825.  
  826.    #
  827.    # update the message line.
  828.    #
  829.    show_message(FALSE)
  830.    return ret
  831. }
  832.  
  833. #
  834. # Global function to process ISPF Primary Commands
  835. #
  836. global function isrexec(command, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
  837. {
  838.    local i
  839.    local ret
  840.    local cmd
  841.    local cmd2
  842.    local args
  843.    local line
  844.  
  845.    ispf_te_mode = FALSE # Reset TE Mode.
  846.  
  847.    command      = trim(ltrim(command))
  848.    i            = cindex(command, " \t")
  849.  
  850.    if (i)
  851.    {
  852.       args    = ltrim(substr(command, i))
  853.       command = substr(command, 1, i-1)
  854.    }
  855.  
  856.    if (argcount() >= 2)
  857.    {
  858.       args = args " " arg1
  859.       if (argcount() >= 3)
  860.       {
  861.          args = args " " arg2
  862.          if (argcount() >= 4)
  863.          {
  864.             args = args " " arg3
  865.             if (argcount() >= 5)
  866.             {
  867.                args = args " " arg4
  868.                if (argcount() >= 6)
  869.                {
  870.                   args = args " " arg5
  871.                   if (argcount() >= 7)
  872.                   {
  873.                      args = args " " arg6
  874.                      if (argcount() >= 8)
  875.                      {
  876.                         args = args " " arg7
  877.                         if (argcount() >= 9)
  878.                            args = args " " arg8
  879.                      }
  880.                   }
  881.                }
  882.             }
  883.          }
  884.       }
  885.    }
  886.  
  887.    cmd = toupper(command)
  888.    if (cmd in ispf_primary)
  889.    {
  890.       cmd2       = ispf_primary[cmd]
  891.       lc_command = cmd
  892.       if (length(args))
  893.          line = cmd2 " " args
  894.       else
  895.          line = cmd2
  896.    }
  897.    else if (length(args))
  898.       line = command " " args
  899.    else
  900.       line = command
  901.  
  902.    # DON'T push undo info for UNDO & REDO or it will break redo!!!!!!!!!
  903.    if (cmd2 != "ispf_undo" && cmd2 != "ispf_redo")
  904.       ispf_push_undo()
  905.  
  906.    if (cmd2 == "ispf_reset")           # RESET doesn't process_commands first
  907.       ret = invoke_function(line)
  908.    else if (process_line_commands())
  909.       ret = invoke_function(line)
  910.  
  911.    show_message(FALSE)
  912.    return ret
  913. }
  914.  
  915. #
  916. # Global function to execute ISPF Line Commands from the command line
  917. #
  918. function islexec(cmd, lptr, arg)
  919. {
  920.    lc_restore = 1
  921.    lc_line    = (argcount() >= 1 && lptr) ? find_label(lptr) : current_line
  922.    lc_arg     = (argcount() >= 2 && arg)  ? arg+0            : 0
  923.  
  924.    if (!lc_arg)
  925.    {
  926.       if (cmd == "TS" || cmd == "TF")
  927.          lc_arg = current_column
  928.       else
  929.          lc_arg = 1
  930.    }
  931.  
  932.    if (cmd in lc)
  933.       return invoke_function(lc[cmd])
  934.    else
  935.       return invoke_function(cmd)
  936. }
  937.  
  938. #
  939. # Global function to push an entry onto ispf's undo stack
  940. #
  941. global function ispf_push_undo()
  942. {
  943.    local i
  944.    local index = ispf_undo_index[current_buffer]
  945.  
  946.    if (ispf_undo_stack[current_buffer][index] != undo_index())
  947.    {
  948.       if (index > ispf_undo_size)
  949.       {
  950.          for (i in ispf_undo_stack[current_buffer])
  951.          {
  952.             ispf_undo_stack[current_buffer][i] = ispf_undo_stack[current_buffer] \
  953.                                                                 [i+1]
  954.          }
  955.          index = ispf_undo_size
  956.       }
  957.       else
  958.       {
  959.          index++
  960.          ispf_undo_index[current_buffer]     = index
  961.          if (ispf_last_index[current_buffer] < index)
  962.              ispf_last_index[current_buffer] = index
  963.       }
  964.       ispf_undo_stack[current_buffer][index] = undo_index()
  965.    }
  966. }
  967.  
  968. #
  969. # Global function to pop an entry from ispf's undo stack (and undo it)
  970. #
  971. global function ispf_undo()
  972. {
  973.    if (ispf_undo_index[current_buffer])
  974.       undo(ispf_undo_stack[current_buffer][--ispf_undo_index[current_buffer]])
  975.    else
  976.       undo()
  977. }
  978.  
  979. #
  980. # Global function to redo an ispf_undo
  981. #
  982. global function ispf_redo()
  983. {
  984.    if (ispf_undo_index[current_buffer] < ispf_last_index[current_buffer])
  985.       redo(ispf_undo_stack[current_buffer][ispf_undo_index[current_buffer]++])
  986.    else
  987.       redo()
  988. }
  989.  
  990. #
  991. # Global function to browse a file (open in Read-Only mode)
  992. #
  993. global function browse_file( fn )
  994. {
  995.    if ( !fn )
  996.       fn = prompt_history( "EDITFILE", "File: ", "" )
  997.  
  998.    if( fn )
  999.    {
  1000.       if (filesize( fn ) > 0)
  1001.       {
  1002.          if( create_buf_and_win( fn ))
  1003.          {
  1004.             buffer_flags = or(buffer_flags, BUFFER_READ_ONLY)
  1005.             display_filename()
  1006.          }
  1007.          else
  1008.             error( "Cannot open file '%s'", fn )
  1009.       }
  1010.       else
  1011.          error( "File '%s' does not exist", fn )
  1012.    }
  1013. }
  1014.  
  1015. #
  1016. # Global function to find a labeled line
  1017. #
  1018. global function find_label(arg)
  1019. {
  1020.    local i
  1021.    local label
  1022.    local line  = 0
  1023.  
  1024.    if (isdigit(arg))
  1025.       line = atoi(arg)
  1026.    else
  1027.    {
  1028.       label = toupper(trim(ltrim(arg)))
  1029.  
  1030.       if (label == ".ZF" || label == ".ZFIRST")
  1031.          line = 1
  1032.    
  1033.       else if (label == ".ZL" || label == ".ZLAST")
  1034.          line = buffer_last_line
  1035.    
  1036.       else if (label == ".ZCSR" || label == ".ZCURSOR")
  1037.          line = current_line
  1038.    
  1039.       else
  1040.       {
  1041.          for ( i in line_command )
  1042.          {
  1043.             if (trim(ltrim(line_command[i])) == label)
  1044.             {
  1045.                line               = atoi(i)
  1046.                line_command[line] = label
  1047.                break
  1048.             }
  1049.          }
  1050.       }
  1051.    }
  1052.    return line
  1053. }
  1054.  
  1055. #
  1056. # Global function to mark the lines between two labeled lines
  1057. #
  1058. global function mark_range(select, from, to, col1, col2)
  1059. {
  1060.    local colsOK
  1061.    local toLine
  1062.    local fromLine
  1063.    local useCols  = (argcount() >= 4)
  1064.  
  1065.    if (argcount() == 0)
  1066.       select = 0
  1067.  
  1068.    else if (useCols)
  1069.    {
  1070.       if (!from)
  1071.       {
  1072.          from = 1
  1073.          if (!to)
  1074.             to = buffer_last_line
  1075.       }
  1076.    }
  1077.  
  1078.    if (argcount() >= 2 && from)
  1079.    {
  1080.       fromLine = find_label(from)
  1081.       if (fromLine)
  1082.       {
  1083.          if (argcount() >= 3 && to)
  1084.          {
  1085.             if (!select)
  1086.             {
  1087.                lc_arg     = 1
  1088.                lc_line    = fromLine
  1089.                lc_command = ".line"
  1090.                if (useCols)
  1091.                   mark_cols(col1, col2)
  1092.                else
  1093.                   mark_cols()
  1094.             }
  1095.  
  1096.             toLine  = find_label(to)
  1097.             if (toLine)
  1098.             {
  1099.                if (select)
  1100.                {
  1101.                   if (useCols)
  1102.                   {
  1103.                      colsOK = (col1 < col2)
  1104.                      if (fromLine < toLine)
  1105.                      {
  1106.                         create_linecol_selection(COLUMN_SELECTION,
  1107.                                                  fromLine, colsOK ? col1 : col2,
  1108.                                                  toLine, colsOK ? col2 : col1)
  1109.                         goto_pos(fromLine, colsOK ? col1 : col2)
  1110.                      }
  1111.                      else
  1112.                      {
  1113.                         create_linecol_selection(COLUMN_SELECTION,
  1114.                                                  toLine, colsOK ? col1 : col2,
  1115.                                                  fromLine, colsOK ? col2 : col1)
  1116.                         goto_pos(toLine, colsOK ? col1 : col2)
  1117.                      }
  1118.                   }
  1119.                   else
  1120.                   {
  1121.                      if (fromLine <= toLine)
  1122.                      {
  1123.                         create_linecol_selection(LINE_SELECTION, fromLine, 1,
  1124.                                                                  toLine,   1)
  1125.                         goto_line(fromLine)
  1126.                      }
  1127.                      else
  1128.                      {
  1129.                         create_linecol_selection(LINE_SELECTION, toLine,   1,
  1130.                                                                  fromLine, 1)
  1131.                         goto_line(toLine)
  1132.                      }
  1133.                   }
  1134.                }
  1135.                else
  1136.                {
  1137.                   lc_line = toLine
  1138.                   if (useCols)
  1139.                      mark_cols(col1, col2)
  1140.                   else
  1141.                      mark_cols()
  1142.                }
  1143.             }
  1144.             else
  1145.             {
  1146.                error("Invalid label %s", to)
  1147.                return FALSE
  1148.             }
  1149.          }
  1150.          else
  1151.          {
  1152.             if (select)
  1153.             {
  1154.                create_linecol_selection(LINE_SELECTION, fromLine, 1, fromLine, 1)
  1155.                goto_line(fromLine)
  1156.             }
  1157.             else
  1158.             {
  1159.                lc_arg     = 1
  1160.                lc_line    = fromLine
  1161.                lc_command = ".line"
  1162.                mark_1_line()
  1163.             }
  1164.          }
  1165.       }
  1166.       else
  1167.       {
  1168.          error("Invalid label %s", from)
  1169.          return FALSE
  1170.       }
  1171.    }
  1172.    else if (select)
  1173.    {
  1174.       error("No range to select")
  1175.       return FALSE
  1176.    }
  1177.    return TRUE
  1178. }
  1179.  
  1180. global function ispf_enter()
  1181. {
  1182.    if (ispf_enter_mode)
  1183.       ispf_execute()
  1184.    else
  1185.       ispf_cr()
  1186. }
  1187.  
  1188. global function ispf_return()
  1189. {
  1190.    if (ispf_enter_mode)
  1191.       ispf_cr()
  1192.    else
  1193.       ispf_execute()
  1194. }
  1195.  
  1196. global function ispf_execute(cmd)
  1197. {
  1198.    local line
  1199.    ispexec(cmd)
  1200.    if (lc_restore)
  1201.    {
  1202.       down()
  1203.       if (auto_indent_mode)
  1204.       {
  1205.          skip_whitespace()
  1206.          if (!read_buffer( 1 ))
  1207.          {
  1208.             line = current_line
  1209.             do {
  1210.                prev_line()
  1211.             } while( current_line > 1 && !read_buffer( 1 ))
  1212.             current_line = line
  1213.          }
  1214.       }
  1215.       else
  1216.          goto_window_left()
  1217.    }
  1218. }
  1219.  
  1220. global function ispf_cr()
  1221. {
  1222.    if( !ispf_cr_mode )
  1223.    {
  1224.       if (current_line >= buffer_last_line)
  1225.       {
  1226.          goto_bolc()
  1227.          beep()
  1228.          return
  1229.       }
  1230.       else
  1231.          down()
  1232.  
  1233.       if (!ispf_te_mode && (current_column < 1 || ispf_tab_mode))
  1234.          goto_bolc()
  1235.       else
  1236.          goto_window_left()
  1237.    }
  1238.    else if( auto_indent_mode ) 
  1239.       insert_auto_indent()
  1240.    else 
  1241.       insert_newline()
  1242. }
  1243.  
  1244. global function ispf_tab()
  1245. {
  1246.    if (ispf_te_mode)
  1247.    {
  1248.       down()
  1249.       goto_pos(0, window_margin + 1)
  1250.    }
  1251.    else if (current_column < 1)
  1252.       goto_pos(0, window_margin + 1)
  1253.  
  1254.    else if( ispf_tab_mode )
  1255.    {
  1256.       down()
  1257.       goto_bolc()
  1258.    }
  1259.    else if( selection_type() || !and(buffer_flags, BUFFER_OVERTYPE_MODE))
  1260.    {
  1261.       indent_tab_maybe()
  1262.    }
  1263.    else
  1264.       goto_next_tab()
  1265. }
  1266.  
  1267. global function ispf_backtab()
  1268. {
  1269.    if (ispf_te_mode)
  1270.    {
  1271.       up()
  1272.       goto_pos(0, window_margin + 1)
  1273.    }
  1274.    else if( ispf_tab_mode )
  1275.    {
  1276.       if (current_column < 1)
  1277.          goto_pos(current_line - 1, window_margin + 1)
  1278.       else
  1279.          goto_bolc()
  1280.    }
  1281.    else if (current_column == 1 && !selection_type())
  1282.       goto_bolc()
  1283.    else
  1284.       outdent_tab_maybe()
  1285. }
  1286.  
  1287. global function ispf_center_key()
  1288. {
  1289.    if (ispf_home_mode)
  1290.    {
  1291.       if (ispf_motion_mode)
  1292.          ispf_home()
  1293.       else
  1294.          home_key(current_key)
  1295.    }
  1296.    else
  1297.       ispf_command()
  1298. }
  1299.  
  1300. global function ispf_home_key()
  1301. {
  1302.    if (ispf_home_mode)
  1303.       ispf_command()
  1304.    else if (ispf_motion_mode)
  1305.       ispf_home()
  1306.    else
  1307.       home_key()
  1308. }
  1309.  
  1310. global function ispf_end_key()
  1311. {
  1312.    if (ispf_motion_mode)
  1313.       ispf_end()
  1314.    else
  1315.       end_key()
  1316. }
  1317.  
  1318. global function ispf_home()
  1319. {
  1320.    goto_window_top()
  1321.    goto_window_left()
  1322. }
  1323.  
  1324. global function ispf_end()
  1325. {
  1326.    if (current_line_width <= window_margin + window_text_width - linenumber_width)
  1327.       goto_eol()
  1328.    else
  1329.       goto_window_right()
  1330. }
  1331.  
  1332. global function ispf_up(amt)
  1333. {
  1334.    if (argcount() < 1)
  1335.       amt = ispf_scroll_amt
  1336.    else
  1337.       amt = toupper(amt)
  1338.  
  1339.    if (amt == "C" || amt == "CSR" || amt == "CRSR" || amt == "CURSOR")
  1340.    {
  1341.       amt = current_line - window_first - window_text_height + 1
  1342.       if (amt)
  1343.          scroll_vertical(amt)
  1344.       else
  1345.          page_up()
  1346.    }
  1347.    else if (amt == "M" || amt == "MAX")
  1348.       scroll_vertical(-window_first + 1)
  1349.    else if (amt == "H" || amt == "HALF")
  1350.       scroll_vertical(-(window_text_height / 2))
  1351.    else if (amt == "P" || amt == "PAGE")
  1352.       scroll_vertical(-window_text_height)
  1353.    else if (amt == "D" || amt == "DATA")
  1354.       page_up()
  1355.    else if (isdigit(amt))
  1356.       scroll_vertical(-amt)
  1357.    else
  1358.       error("Invalid Scroll Amount %s", amt)
  1359.  
  1360.    current_line = window_first + window_text_height - 1
  1361.    update_current_view()
  1362. }
  1363.  
  1364. global function ispf_down(amt)
  1365. {
  1366.    if (argcount() < 1)
  1367.       amt = ispf_scroll_amt
  1368.    else
  1369.       amt = toupper(amt)
  1370.  
  1371.    if (amt == "C" || amt == "CSR" || amt == "CRSR" || amt == "CURSOR")
  1372.    {
  1373.       amt = current_line - window_first
  1374.       if (amt)
  1375.          scroll_vertical(amt)
  1376.       else
  1377.          page_down()
  1378.    }
  1379.    else if (amt == "M" || amt == "MAX")
  1380.       scroll_vertical(buffer_last_line - window_first - window_text_height + 2)
  1381.    else if (amt == "H" || amt == "HALF")
  1382.       scroll_vertical(window_text_height / 2)
  1383.    else if (amt == "P" || amt == "PAGE")
  1384.       scroll_vertical(window_text_height)
  1385.    else if (amt == "D" || amt == "DATA")
  1386.       page_down()
  1387.    else if (isdigit(amt))
  1388.       scroll_vertical(amt)
  1389.    else
  1390.       error("Invalid Scroll Amount %s", amt)
  1391.  
  1392.    current_line = window_first
  1393.    update_current_view()
  1394. }
  1395.  
  1396. global function ispf_left(amt)
  1397. {
  1398.    local width
  1399.  
  1400.    if (argcount())
  1401.       amt = toupper(amt)
  1402.    else
  1403.       amt = ispf_scroll_amt
  1404.  
  1405.    if (amt == "C" || amt == "CSR" || amt == "CRSR" || amt == "CURSOR")
  1406.    {
  1407.       width = window_text_width - linenumber_width
  1408.       amt   = window_margin + width - current_column
  1409.       if (amt > 0 && amt < width - 1)
  1410.          scroll_horizontal(-amt)
  1411.       else
  1412.          left_page()
  1413.    }
  1414.    else if (amt == "M" || amt == "MAX")
  1415.       goto_bol()
  1416.    else if (amt == "H" || amt == "HALF")
  1417.       left_half_page()
  1418.    else if (amt == "P" || amt == "PAGE")
  1419.       left_page()
  1420.    else if (amt == "D" || amt == "DATA")
  1421.       scroll_horizontal(-(window_text_width - linenumber_width) + 1)
  1422.    else if (isdigit(amt))
  1423.       scroll_horizontal(-amt)
  1424.    else
  1425.       error("Invalid Scroll Amount %s", amt)
  1426.  
  1427.    goto_window_left()
  1428. }
  1429.  
  1430. global function ispf_right(amt)
  1431. {
  1432.    if (argcount())
  1433.       amt = toupper(amt)
  1434.    else
  1435.       amt = ispf_scroll_amt
  1436.  
  1437.    if (amt == "C" || amt == "CSR" || amt == "CRSR" || amt == "CURSOR")
  1438.    {
  1439.       amt = current_column - window_margin - 1
  1440.       if (amt > 0 && amt < window_text_width - linenumber_width)
  1441.          scroll_horizontal(amt)
  1442.       else
  1443.          right_page()
  1444.    }
  1445.    else if (amt == "M" || amt == "MAX")
  1446.       scroll_horizontal(wp_right_margin - current_column + window_text_width)
  1447.    else if (amt == "H" || amt == "HALF")
  1448.       right_half_page()
  1449.    else if (amt == "P" || amt == "PAGE")
  1450.       right_page()
  1451.    else if (amt == "D" || amt == "DATA")
  1452.       scroll_horizontal((window_text_width - linenumber_width) - 1)
  1453.    else if (isdigit(amt))
  1454.       scroll_horizontal(amt)
  1455.    else
  1456.       error("Invalid Scroll Amount %s", amt)
  1457.  
  1458.    goto_window_left()
  1459. }
  1460.  
  1461. global function ispf_text_entry()
  1462. {
  1463.    ispf_te_mode = TRUE
  1464.    lc_arg       = max(lc_arg, window_text_height + 1)
  1465.    return insert_lines()
  1466. }
  1467.  
  1468. global function ispf_text_split()
  1469. {
  1470.    local OK
  1471.    local old_flags = buffer_flags
  1472.  
  1473.    restore_position(1)
  1474.    save_position()
  1475.    goto_pos(lc_line, 0)
  1476.  
  1477.    buffer_flags = and(old_flags, not(BUFFER_OVERTYPE_MODE ))
  1478.    OK           = insert_auto_indent(1)
  1479.    buffer_flags = old_flags
  1480.    lc_restore   = 0
  1481.  
  1482.    if (OK)
  1483.       return LC_OK
  1484.    else
  1485.       return LC_NOTOK
  1486. }
  1487.  
  1488. global function ispf_text_join()
  1489. {
  1490.    goto_line(lc_line)
  1491.    goto_eol()
  1492.  
  1493.    if (delete_chars())
  1494.       return LC_OK
  1495.    else
  1496.       return LC_NOTOK
  1497. }
  1498.  
  1499. global function ispf_copy_file( fn, where, lptr, from, to )
  1500. {
  1501.    local pos
  1502.    local line
  1503.    local old_flags
  1504.    local after        = FALSE
  1505.    local before       = FALSE
  1506.    local result       = FALSE
  1507.    local numargs      = argcount()
  1508.    local on_last_line = FALSE
  1509.  
  1510.    if ( !fn )
  1511.    {
  1512.       fn = prompt_history( "EDITFILE", "File to read: ", "" )
  1513.       if ( !fn )
  1514.          return
  1515.    }
  1516.  
  1517.    if ( fn )
  1518.    {
  1519.       if (numargs > 1 && length(where))
  1520.       {
  1521.          where  = toupper(where)
  1522.          before = (where == "BEFORE" || where == "B")
  1523.          if (!before)
  1524.             after = (where == "AFTER" || where == "A")
  1525.    
  1526.          if (!before && !after)
  1527.          {
  1528.             from = where
  1529.             to   = lptr
  1530.          }
  1531.          else if (numargs >= 3 && length(lptr))
  1532.             line = find_label(lptr)
  1533.          else
  1534.          {
  1535.             error("Invalid BEFORE or AFTER clause specified")
  1536.             return
  1537.          }
  1538.       }
  1539.  
  1540.       if (length(from) || length(to))
  1541.       {
  1542.          error("The line-range is not yet supported in the COPY and MOVE commands")
  1543.          return
  1544.       }
  1545.  
  1546.       if (line)
  1547.       {
  1548.          goto_line(line)
  1549.          goto_bol()
  1550.       }
  1551.       else if (tr_count)
  1552.       {
  1553.          if (current_buffer != tr_dest_buffer)
  1554.              current_buffer  = tr_dest_buffer
  1555.  
  1556.          goto_mark(tr_dest_mark)
  1557.       }
  1558.       else
  1559.       {
  1560.          error("No Destination specified for the COPY or MOVE")
  1561.          return
  1562.       }
  1563.  
  1564.       # make sure the buffer is NOT read-only so it won't play havok with
  1565.       # the newline games we might need to play.
  1566.       if ( and(buffer_flags, BUFFER_READ_ONLY) )
  1567.       {
  1568.          error("Read only file.")
  1569.          return
  1570.       }
  1571.  
  1572.       on_last_line = (current_line >= buffer_last_line)
  1573.       if (on_last_line)
  1574.       {
  1575.          if (tr_after || after)
  1576.          {
  1577.             # if we insert something AFTER the last line, we need to move
  1578.             # to the end of the line and save that position so we can
  1579.             # insert a newline there if the copy is sucessful.
  1580.             goto_eol()
  1581.             pos = create_mark(pick_unused_mark())
  1582.          }
  1583.          else if (current_line_length) # The normal method will work if the
  1584.             on_last_line = FALSE       # last line has something on it.
  1585.          else                          # otherwise we'll just back up before
  1586.             prev_char()                # the last cr & insert one at the end
  1587.       }                                # later.
  1588.       else if (tr_after || after)
  1589.          down()
  1590.  
  1591.       if (!on_last_line)
  1592.       {
  1593.          # mark the next_char which will be the first char after the read.
  1594.          # (if we mark this char, it won't be moved by the read)
  1595.          next_char()
  1596.          pos = create_mark(pick_unused_mark())
  1597.          prev_char()
  1598.       }
  1599.  
  1600.       if ((result = read_file( fn )))
  1601.       {
  1602.          if (on_last_line)
  1603.          {
  1604.             if (tr_after || after)
  1605.                goto_mark(pos) # restore saved pos
  1606.          }
  1607.          else
  1608.          {
  1609.             goto_mark(pos) # restore saved pos
  1610.             prev_char()    # backup since we saved the pos of the NEXT char.
  1611.          }
  1612.  
  1613.          # insert a newline in the buffer since the file we read probaby
  1614.          # doesn't have a new as the last char, which would cause the last
  1615.          # line of the file and the next line in the buffer to be joined.
  1616.          # OR - we just inserted the file at the end and the last line of
  1617.          # the buffer just got joined to the first line of the file.
  1618.          old_flags    = buffer_flags
  1619.          buffer_flags = and(buffer_flags, not(BUFFER_OVERTYPE_MODE))
  1620.          insert_newline()
  1621.          buffer_flags = old_flags
  1622.  
  1623.          if (!line && tr_count)
  1624.          {
  1625.             # if we were copying after the last line, we need to move the
  1626.             # dest mark there since the line_command will have been pushed
  1627.             # there by the read.
  1628.             if (on_last_line)
  1629.             {
  1630.                goto_buffer_bottom()
  1631.                delete_mark(tr_dest_mark)
  1632.                tr_dest_mark = create_mark(pick_unused_mark())
  1633.             }
  1634.             else if (!(tr_after || after))
  1635.             {
  1636.                # if we read the data BEFORE the mark, we need to move the mark
  1637.                # so that reset_transfer() will delete the correct line-command.
  1638.                delete_mark(tr_dest_mark)
  1639.                tr_dest_mark = pos
  1640.             }
  1641.             reset_transfer(LC_OK, TRUE)
  1642.          }
  1643.          else if (!on_last_line)
  1644.             delete_mark(pos)
  1645.  
  1646.          update_current_view()
  1647.       }
  1648.       else
  1649.          delete_mark(pos)
  1650.    }
  1651.    return result
  1652. }
  1653.  
  1654. global function ispf_move_file( fn, where, lptr)
  1655. {
  1656.    if (ispf_copy_file(fn, where, lptr))
  1657.    {
  1658.       system("del " fn)
  1659.       return TRUE
  1660.    }
  1661.    else
  1662.       return FALSE
  1663. }
  1664.  
  1665. global function ispf_create_file( fn, from, to )
  1666. {
  1667.    if (substr(fn, 1, 1) == ".")
  1668.    {
  1669.       to   = from
  1670.       from = fn
  1671.       fn   = ""
  1672.       delete fn
  1673.    }
  1674.  
  1675.    if (!fn)
  1676.       fn = prompt( "File to create: ", "" )
  1677.  
  1678.    if (fn)
  1679.    {
  1680.       if (filesize(fn) <= 0)
  1681.       {
  1682.          if (argcount() > 1)
  1683.             ispf_write_file(fn, from, to)
  1684.          else
  1685.             ispf_write_file(fn)
  1686.       }
  1687.       else
  1688.          error("Unable to create file, %s already exists", fn)
  1689.    }
  1690. }
  1691.  
  1692. global function ispf_replace_file( fn, from, to )
  1693. {
  1694.    if (substr(fn, 1, 1) == ".")
  1695.    {
  1696.       to   = from
  1697.       from = fn
  1698.       fn   = ""
  1699.       delete fn
  1700.    }
  1701.  
  1702.    if (!fn)
  1703.       fn = prompt_history( "EDITFILE", "File to replace: ", "" )
  1704.  
  1705.    if (fn)
  1706.    {
  1707.       if (argcount() > 1)
  1708.          ispf_write_file(fn, from, to)
  1709.       else
  1710.          ispf_write_file(fn)
  1711.    }
  1712. }
  1713.  
  1714. global function ispf_write_file( fn, from, to )
  1715. {
  1716.    local old_name = buffer_filename
  1717.  
  1718.    if (argcount() > 1)
  1719.    {
  1720.       if (!mark_range(0, from, to))
  1721.          return
  1722.    }
  1723.  
  1724.    tr_write_file = fn
  1725.    if (perform_transfer("write_marked_lines") >= LC_NOTOK)
  1726.    {
  1727.       change_output_name( fn )
  1728.       write_buffer()
  1729.       change_output_name( old_name )
  1730.    }
  1731.    delete tr_write_file
  1732. }
  1733.  
  1734. global function ispf_cut( from, to )
  1735. {
  1736.    if (argcount())
  1737.    {
  1738.       if (!mark_range(0, from, to))
  1739.          return
  1740.    }
  1741.    perform_transfer("cut_marked_lines")
  1742. }
  1743.  
  1744. global function ispf_paste(where, lptr)
  1745. {
  1746.    local line
  1747.    local after   = FALSE
  1748.    local before  = FALSE
  1749.    local result  = FALSE
  1750.    local numargs = argcount()
  1751.  
  1752.    if (numargs && length(where))
  1753.    {
  1754.       where  = toupper(where)
  1755.       before = (where == "BEFORE" || where == "B")
  1756.       if (!before)
  1757.          after = (where == "AFTER" || where == "A")
  1758.  
  1759.       if (numargs >= 2 && length(lptr))
  1760.          line = find_label(lptr)
  1761.       else
  1762.       {
  1763.          error("Invalid BEFORE or AFTER clause specified")
  1764.          return
  1765.       }
  1766.    }
  1767.  
  1768.    if (line)
  1769.    {
  1770.       goto_line(line)
  1771.       goto_bol()
  1772.    }
  1773.    else if (tr_count)
  1774.    {
  1775.       if (current_buffer != tr_dest_buffer)
  1776.           current_buffer  = tr_dest_buffer
  1777.       goto_mark(tr_dest_mark)
  1778.       if (tr_after)
  1779.          down()
  1780.    }
  1781.    else
  1782.    {
  1783.       error("No Destination specified for the PASTE")
  1784.       return
  1785.    }
  1786.  
  1787.    if ((result = insert_scrap()))
  1788.    {
  1789.       if (!line && tr_count)
  1790.          reset_transfer(LC_OK, TRUE)
  1791.  
  1792.       update_current_view()
  1793.    }
  1794.    return result
  1795. }
  1796.  
  1797. function ispf_find( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 )
  1798. {
  1799.    local result, count
  1800.  
  1801.    if (ispf_parse_find( FALSE, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 ))
  1802.    {
  1803.       if (and(ispf_flags, ISPF_PROMPT))
  1804.       {
  1805.          result = find_all( search_pattern, 1 )
  1806.          count  = result[0]
  1807.       }
  1808.       else if (and(ispf_flags, ISPF_ALL))
  1809.       {
  1810.          result = find_all( search_pattern, 0 )
  1811.          count  = result[0]
  1812.       }
  1813.       else
  1814.          count = string_search( search_pattern )
  1815.  
  1816.       rfind_failed = (count == 0)
  1817.       return count
  1818.    }
  1819.    else
  1820.       return -1
  1821. }
  1822.  
  1823. function ispf_change( arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 )
  1824. {
  1825.    local count
  1826.    search_flags = or(search_flags, SEARCH_HIGHLIGHT)
  1827.  
  1828.    if (ispf_parse_find(TRUE, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8))
  1829.    {
  1830.       if (rfind_key)
  1831.       {
  1832.          ispf_rfind()
  1833.          return 0
  1834.       }
  1835.       else
  1836.       {
  1837.          count = string_replace( search_pattern, replace_pattern )
  1838.  
  1839.          if (and(ispf_flags, ISPF_BLOCK))
  1840.             remove_selection()
  1841.  
  1842.          rfind_failed = (count == 0)
  1843.          return count
  1844.       }
  1845.    }
  1846.    else
  1847.       return -1
  1848. }
  1849.  
  1850. function ispf_rfind()
  1851. {
  1852.    if (rfind_failed)
  1853.       search_flags = or(search_flags, SEARCH_WRAPS)
  1854.    else
  1855.       search_flags = and(search_flags, not(SEARCH_WRAPS))
  1856.  
  1857.    rfind_failed = !search_again()
  1858. }
  1859.  
  1860. function ispf_rchange()
  1861. {
  1862.    if (rfind_failed)
  1863.       search_flags = or(search_flags, SEARCH_WRAPS)
  1864.    else
  1865.       search_flags = and(search_flags, not(SEARCH_WRAPS))
  1866.  
  1867.    rfind_failed = !replace_again(1) # do NOT advance before changing!
  1868. }
  1869.  
  1870. #
  1871. # Function to parse an ISPF find or change command
  1872. #
  1873. local function ispf_parse_find( change, arg1, arg2, arg3, arg4,
  1874.                                         arg5, arg6, arg7, arg8 )
  1875. {
  1876.    local i
  1877.    local args
  1878.    local from, to
  1879.    local col1, col2
  1880.  
  1881.    local numargs   = argcount()
  1882.    local wordchars = "A-Za-z0-9#$@"
  1883.    local isword    = "[" wordchars "]"
  1884.    local noword    = "[^" wordchars "]"
  1885.  
  1886.    ispf_flags = ispf_default
  1887.  
  1888.    # get the search_pattern
  1889.  
  1890.    if ( numargs == 0 || length(arg1) == 0)
  1891.    {
  1892.       search_pattern = ispf_parse_pattern()
  1893.    }
  1894.    else if (arg1 != "*")
  1895.       search_pattern = ispf_parse_pattern(arg1)
  1896.  
  1897.    # get the replace_pattern if it's needed
  1898.  
  1899.    if (change)
  1900.    {
  1901.       if (numargs < 2 || length(arg2) == 0)
  1902.          replace_pattern = ispf_parse_pattern("", TRUE)
  1903.       else if (arg2 != "*")
  1904.          replace_pattern = ispf_parse_pattern(arg2, TRUE)
  1905.  
  1906.       if (numargs > 2 && length(arg3))
  1907.       {
  1908.          numargs -= 2
  1909.          args[1]  = toupper(arg3)
  1910.          args[2]  = toupper(arg4)
  1911.          args[3]  = toupper(arg5)
  1912.          args[4]  = toupper(arg6)
  1913.          args[5]  = toupper(arg7)
  1914.          args[6]  = toupper(arg8)
  1915.       }
  1916.       else
  1917.          numargs = 0
  1918.    }
  1919.    else if (numargs > 1 && length(arg2))
  1920.    {
  1921.       numargs--
  1922.       args[1] = toupper(arg2)
  1923.       args[2] = toupper(arg3)
  1924.       args[3] = toupper(arg4)
  1925.       args[4] = toupper(arg5)
  1926.       args[5] = toupper(arg6)
  1927.       args[6] = toupper(arg7)
  1928.       args[7] = toupper(arg8)
  1929.    }
  1930.    else
  1931.       numargs = 0
  1932.  
  1933.    if (numargs > 1)
  1934.    {
  1935.       # get the rest of the find/change arguments and set the ispf_flags
  1936.    
  1937.       for(i = 1; i <= numargs; i++)
  1938.       {
  1939.          if (length(args[i]))
  1940.          {
  1941.             if (isdigit(args[i]))                  # columns
  1942.             {
  1943.                if (col1)
  1944.                    col2 = args[i]
  1945.                else
  1946.                    col1 = args[i]
  1947.             }
  1948.             else if (substr(args[i], 1, 1) == ".") # lines
  1949.             {
  1950.                if (from)
  1951.                   to   = args[i]
  1952.                else
  1953.                   from = args[i]
  1954.             }
  1955.             else if (args[i] == "ALL")
  1956.             {
  1957.                if (and(ispf_flags, ISPF_DIRS))
  1958.                {
  1959.                   error("Only one of ALL/NEXT/PREV/FIRST/LAST/PROMPT may be specified")
  1960.                   ispf_flags += ISPF_ERROR
  1961.                   return FALSE
  1962.                }
  1963.                else
  1964.                   ispf_flags += ISPF_ALL
  1965.             }
  1966.             else if (args[i] == "PROMPT" || args[i] == "PRO")
  1967.             {
  1968.                if (and(ispf_flags, ISPF_DIRS))
  1969.                {
  1970.                   error("Only one of ALL/NEXT/PREV/FIRST/LAST/PROMPT may be specified")
  1971.                   ispf_flags += ISPF_ERROR
  1972.                   return FALSE
  1973.                }
  1974.                else
  1975.                   ispf_flags += ISPF_PROMPT
  1976.             }
  1977.             else if (args[i] == "NEXT")
  1978.             {
  1979.                if (and(ispf_flags, ISPF_DIRS))
  1980.                {
  1981.                   error("Only one of ALL/NEXT/PREV/FIRST/LAST/PROMPT may be specified")
  1982.                   ispf_flags += ISPF_ERROR
  1983.                   return FALSE
  1984.                }
  1985.                else
  1986.                   ispf_flags += ISPF_NEXT
  1987.             }
  1988.             else if (args[i] == "PREV")
  1989.             {
  1990.                if (and(ispf_flags, ISPF_DIRS))
  1991.                {
  1992.                   error("Only one of ALL/NEXT/PREV/FIRST/LAST/PROMPT may be specified")
  1993.                   ispf_flags += ISPF_ERROR
  1994.                   return FALSE
  1995.                }
  1996.                else
  1997.                   ispf_flags += ISPF_PREV
  1998.             }
  1999.             else if (args[i] == "FIRST")
  2000.             {
  2001.                if (and(ispf_flags, ISPF_DIRS))
  2002.                {
  2003.                   error("Only one of ALL/NEXT/PREV/FIRST/LAST/PROMPT may be specified")
  2004.                   ispf_flags += ISPF_ERROR
  2005.                   return FALSE
  2006.                }
  2007.                else
  2008.                   ispf_flags += ISPF_FIRST
  2009.             }
  2010.             else if (args[i] == "LAST")
  2011.             {
  2012.                if (and(ispf_flags, ISPF_DIRS))
  2013.                {
  2014.                   error("Only one of ALL/NEXT/PREV/FIRST/LAST/PROMPT may be specified")
  2015.                   ispf_flags += ISPF_ERROR
  2016.                   return FALSE
  2017.                }
  2018.                else
  2019.                  ispf_flags += ISPF_LAST
  2020.             }
  2021.  
  2022.             else if ((args[i] == "CHARS"  || args[i] == "CHAR"))
  2023.             {
  2024.                if (and(ispf_flags, ISPF_PARMS))
  2025.                {
  2026.                   error("Only one of CHARS/PREFIX/SUFFIX/WORD may be specified")
  2027.                   ispf_flags += ISPF_ERROR
  2028.                   return FALSE
  2029.                }
  2030.                else
  2031.                  ispf_flags += ISPF_CHARS
  2032.             }
  2033.             else if (args[i] == "PREFIX" || args[i] == "PRE")
  2034.             {
  2035.                if (and(ispf_flags, ISPF_PARMS))
  2036.                {
  2037.                   error("Only one of CHARS/PREFIX/SUFFIX/WORD may be specified")
  2038.                   ispf_flags += ISPF_ERROR
  2039.                   return FALSE
  2040.                }
  2041.                else
  2042.                   ispf_flags += ISPF_PREFIX
  2043.             }
  2044.             else if (args[i] == "SUFFIX" || args[i] == "SUF")
  2045.             {
  2046.                if (and(ispf_flags, ISPF_PARMS))
  2047.                {
  2048.                   error("Only one of CHARS/PREFIX/SUFFIX/WORD may be specified")
  2049.                   ispf_flags += ISPF_ERROR
  2050.                   return FALSE
  2051.                }
  2052.                else
  2053.                   ispf_flags += ISPF_SUFFIX
  2054.             }
  2055.             else if (args[i] == "WORD")
  2056.             {
  2057.                if (and(ispf_flags, ISPF_PARMS))
  2058.                {
  2059.                   error("Only one of CHARS/PREFIX/SUFFIX/WORD may be specified")
  2060.                   ispf_flags += ISPF_ERROR
  2061.                   return FALSE
  2062.                }
  2063.                else
  2064.                   ispf_flags += ISPF_WORD
  2065.             }
  2066.  
  2067.             else if (args[i] == "X")
  2068.             {
  2069.                if (and(ispf_flags, ISPF_EXCLUDE))
  2070.                {
  2071.                   error("Only one of X/NX may be specified")
  2072.                   ispf_flags += ISPF_ERROR
  2073.                   return FALSE
  2074.                }
  2075.                else
  2076.                  ispf_flags += ISPF_X
  2077.             }
  2078.             else if (args[i] == "NX")
  2079.             {
  2080.                if (and(ispf_flags, ISPF_EXCLUDE))
  2081.                {
  2082.                   error("Only one of X/NX may be specified")
  2083.                   ispf_flags += ISPF_ERROR
  2084.                   return FALSE
  2085.                }
  2086.                else
  2087.                  ispf_flags += ISPF_NX
  2088.             }
  2089.  
  2090.             else
  2091.             {
  2092.                error("Invalid parameter %s in find/change command", args[i])
  2093.                ispf_flags += ISPF_ERROR
  2094.                return FALSE
  2095.             }
  2096.          }
  2097.       }
  2098.  
  2099.       # if a range was specified, mark the range.
  2100.  
  2101.       if (from || col1)
  2102.       {
  2103.          ispf_flags = or(ispf_flags, ISPF_BLOCK)
  2104.  
  2105.          if (col1)
  2106.             mark_range(1, from, to, col1, col2)
  2107.          else
  2108.             mark_range(1, from, to)
  2109.       }
  2110.    }
  2111.  
  2112.    # setup the search_count based on the ispf_flags
  2113.  
  2114.    if (and(ispf_flags, ISPF_ALL))
  2115.    {
  2116.       search_flags = or( search_flags, SEARCH_WRAPS )
  2117.       search_count = MAX_SEARCH
  2118.    }
  2119.    else if (and(ispf_flags, ISPF_BLOCK))
  2120.    {
  2121.       search_flags = and( search_flags, not(SEARCH_WRAPS) )
  2122.       search_count = MAX_SEARCH
  2123.    }
  2124.    else if (and(ispf_flags, ISPF_PROMPT))
  2125.    {
  2126.       search_flags = or( search_flags, SEARCH_WRAPS )
  2127.       search_count = 0
  2128.    }
  2129.    else
  2130.    {
  2131.       search_flags = and( search_flags, not(SEARCH_WRAPS) )
  2132.       search_count = 1
  2133.    }
  2134.  
  2135.    # setup the search_flags based on the ispf_flags
  2136.  
  2137.    if (and(ispf_flags, ISPF_FIRST))
  2138.    {
  2139.       goto_line(1)
  2140.       search_flags = or(search_flags, SEARCH_FORWARD)
  2141.       search_flags = and(search_flags, not(SEARCH_ADVANCE))
  2142.    }
  2143.    else if (and(ispf_flags, ISPF_LAST))
  2144.    {
  2145.       goto_line(buffer_last_line)
  2146.       search_flags = and( search_flags, not( SEARCH_FORWARD ))
  2147.       search_flags = and(search_flags, not(SEARCH_ADVANCE))
  2148.    }
  2149.    else if (and(ispf_flags, ISPF_PREV))
  2150.       search_flags = and( search_flags, not( SEARCH_FORWARD ))
  2151. #  else if (and(ispf_flags, ISPF_NEXT))
  2152. #     search_flags = or( search_flags, SEARCH_FORWARD )
  2153.    else
  2154.       search_flags = or( search_flags, SEARCH_FORWARD )
  2155.  
  2156.    if (and(ispf_flags, ISPF_PREFIX))
  2157.    {
  2158.       search_pattern = "(^|" noword ")\\c{" ispf_escape_regex(search_pattern) "}"
  2159.       search_flags   = or( search_flags, SEARCH_REGEX )
  2160.    }
  2161.    else if (and(ispf_flags, ISPF_SUFFIX))
  2162.    {
  2163.       search_pattern = "{" ispf_escape_regex(search_pattern) "}("noword "|$)"
  2164.       search_flags   = or( search_flags, SEARCH_REGEX )
  2165.    }
  2166.    else if (and(ispf_flags, ISPF_WORD))
  2167.    {
  2168.       search_pattern = "(^|" noword ")\\c{" ispf_escape_regex(search_pattern) \
  2169.                        "}("noword "|$)"
  2170.  
  2171.       search_flags   = or( search_flags, SEARCH_REGEX )
  2172.    }
  2173.    else if (and(ispf_flags, ISPF_REGEX))
  2174.       search_flags = or( search_flags, SEARCH_REGEX )
  2175.    else
  2176.       search_flags = and( search_flags, not( SEARCH_REGEX ))
  2177.  
  2178.    if (and(ispf_flags, ISPF_ICASE))
  2179.       search_flags = and(search_flags, not(SEARCH_CASE))
  2180.    else
  2181.       search_flags = or(search_flags, SEARCH_CASE)
  2182.  
  2183.    if (and(ispf_flags, ISPF_BLOCK))
  2184.       search_flags = or(search_flags, SEARCH_BLOCK)
  2185.    else
  2186.       search_flags = and(search_flags, not(SEARCH_BLOCK))
  2187.  
  2188.    return TRUE
  2189. }
  2190.  
  2191. #
  2192. # Function to parse an ISPF find or change pattern
  2193. #
  2194. local function ispf_parse_pattern(pattern, for_change)
  2195. {
  2196.    local i
  2197.    local ch
  2198.    local len
  2199.    local type
  2200.    local string
  2201.    local result
  2202.    local from_history
  2203.  
  2204.    if (!length(pattern))
  2205.    {
  2206.       if (for_change)
  2207.          pattern = prompt_history("REPLACE", "Replacement: ", replace_pattern )
  2208.       else
  2209.          pattern = prompt_history( "SEARCH", " Search for: ", search_pattern )
  2210.  
  2211.       from_history = TRUE # The pattern could come from the history stack
  2212.    }                      # and therefore might be a REGEX expression.
  2213.  
  2214.    type = toupper(substr(pattern, 1, 2))
  2215.    if (type == "C'" || type == "C\"")      # Characer
  2216.    {
  2217.       result     = substr(pattern, 3, length(pattern)-3) # remove quotes
  2218.       ispf_flags = and(ispf_flags, not(ISPF_ICASE))
  2219.    }
  2220.    else if (type == "X'" || type == "X\"") # heX
  2221.    {
  2222.       string = substr(pattern, 3, length(pattern)-3) # remove quotes
  2223.       len    = length(string)
  2224.  
  2225.       for (i = 1; i <= len; i += 2)
  2226.       {
  2227.          while (index(" \t", substr(string, i, 1)))
  2228.          {
  2229.             if (++i > len)
  2230.                break
  2231.          }
  2232.          if (i <= len)
  2233.          {
  2234.             result = result chr( 0 + ("0x" substr(string, i, 2)))
  2235.          }
  2236.       }
  2237.       ispf_flags = and(ispf_flags, not(ISPF_ICASE))
  2238.    }
  2239.    else if (type == "P'" || type == "P\"") # Picture
  2240.    {
  2241.       string = substr(pattern, 3, length(pattern)-3) # remove quotes
  2242.       len    = length(string)
  2243.  
  2244.       for (i = 1; i <= len; i++)
  2245.       {
  2246.          ch = substr(string,i,1)
  2247.  
  2248.          if (ch == "=")
  2249.             ch = "."
  2250.          else if (ch == "^")
  2251.             ch = "[~ \t]"
  2252.          else if (ch == ".")
  2253.             ch = "[\x01-\x1F\x7F-\xFF]" # PEL doesn't line 0x00
  2254.          else if (ch == "#")
  2255.             ch = "[0-9]"
  2256.          else if (ch == "-")
  2257.             ch = "[~0-9]"
  2258.          else if (ch == "@")
  2259.             ch = "[A-Za-z]"
  2260.          else if (ch == "<")
  2261.             ch = "[a-z]"
  2262.          else if (ch == ">")
  2263.             ch = "[A-Z]"
  2264.          else if (ch == "$")
  2265.             ch = "[~0-9A-Za-z]"
  2266.          else if (index("[]|(){}*+?\"\\", ch))
  2267.             ch = "\\" ch
  2268.  
  2269.          result = result ch
  2270.       }
  2271.       ispf_flags = or(ispf_flags, or(ISPF_REGEX, ISPF_ICASE))
  2272.    }
  2273.    else if (type == "R'" || type == "R\"") # Regex
  2274.    {
  2275.       result     = substr(pattern, 3, length(pattern)-3) # remove quotes
  2276.       ispf_flags = or(ispf_flags, or(ISPF_REGEX, ISPF_ICASE))
  2277.    }
  2278.    else
  2279.    {
  2280.       result = pattern
  2281.  
  2282.       if (from_history && cindex(pattern, "^.<>$[]|(){}*+?\\"))
  2283.          ispf_flags = or(ispf_flags, ISPF_REGEX)
  2284.  
  2285.       if (!for_change)
  2286.          ispf_flags = or(ispf_flags, ISPF_ICASE)
  2287.    }
  2288.  
  2289.    return result
  2290. }
  2291.  
  2292. local function ispf_escape_regex(pattern)
  2293. {
  2294.    local i
  2295.    local ch
  2296.    local len
  2297.    local result
  2298.  
  2299.    if (!and(ispf_flags, ISPF_REGEX) && cindex(pattern, "^.<>$[]|(){}*+?\\"))
  2300.    {
  2301.       len    = length(pattern)
  2302.       for (i = 1; i <= len; i++)
  2303.       {
  2304.          ch = substr(pattern,i,1)
  2305.    
  2306.          if (index("^.<>$[]|(){}*+?\"\\", ch))
  2307.             result = result "\\" ch
  2308.          else
  2309.             result = result ch
  2310.       }
  2311.       return result
  2312.    }
  2313.    else
  2314.       return pattern
  2315. }
  2316.  
  2317. global function ispf_locate(arg1, arg2, arg3, arg4)
  2318. {
  2319.    local dir
  2320.    local argn
  2321.    local line
  2322.    local label
  2323.    local found
  2324.  
  2325.    if (argcount() < 1)
  2326.       goto_line_key()
  2327.    else if (argcount() == 1 && (isdigit(arg1) || substr(arg1,1,1) == "."))
  2328.    {
  2329.       line = find_label(arg1)
  2330.  
  2331.       if (line)
  2332.       {
  2333.          goto_line(line)
  2334.  
  2335.          if (!isdigit(arg1))
  2336.             message("Label %s found", label)
  2337.       }
  2338.       else
  2339.          error("Label %s not found", arg1)
  2340.    }
  2341.    else
  2342.    {
  2343.       arg1 = toupper(arg1)
  2344.  
  2345.       if (arg1 == "NEXT"  || arg1 == "N")
  2346.       {
  2347.          dir  = "N"
  2348.          argn = toupper(arg2)
  2349.       }
  2350.       else if (arg1 == "PREV"  || arg1 == "P")
  2351.       {
  2352.          dir  = "P"
  2353.          argn = toupper(arg2)
  2354.       }
  2355.       else if (arg1 == "FIRST" || arg1 == "F")
  2356.       {
  2357.          dir  = "F"
  2358.          argn = toupper(arg2)
  2359.       }
  2360.       else if (arg1 == "LAST"  || arg1 == "L")
  2361.       {
  2362.          dir  = "L"
  2363.          argn = toupper(arg2)
  2364.       }
  2365.       else
  2366.       {
  2367.          dir  = "N"
  2368.          argn = arg1
  2369.       }
  2370.  
  2371.       if (argn == "LABEL" || argn == "LAB" || argn == "L")
  2372.       {
  2373.          if (argn == arg1)
  2374.             loc_line("L", dir, arg2, arg3)
  2375.          else
  2376.             loc_line("L", dir, arg3, arg4)
  2377.       }
  2378.       else if (argn == "COMMAND"  || argn == "CMD" || argn == "M")
  2379.       {
  2380.          if (argn == arg1)
  2381.             loc_line("M", dir, arg2, arg3)
  2382.          else
  2383.             loc_line("M", dir, arg3, arg4)
  2384.       }
  2385.       else if (argn == "ERROR"    || argn == "ERR" || argn == "E")
  2386.       {
  2387.          if (argn == arg1)
  2388.             loc_line("E", dir, arg2, arg3)
  2389.          else
  2390.             loc_line("E", dir, arg3, arg4)
  2391.       }
  2392.       else if (argn == "CHANGE"   || argn == "CHG" || argn == "C")
  2393.       {
  2394.          if (argn == arg1)
  2395.             loc_line("C", dir, arg2, arg3)
  2396.          else
  2397.             loc_line("C", dir, arg3, arg4)
  2398.       }
  2399.       else if (argn == "SPECIAL"  || argn == "SPE" || argn == "S")
  2400.       {
  2401.          if (argn == arg1)
  2402.             loc_line("S", dir, arg2, arg3)
  2403.          else
  2404.             loc_line("S", dir, arg3, arg4)
  2405.       }
  2406.       else if (argn == "ANY" || argn == "A")
  2407.       {
  2408.          if (argn == arg1)
  2409.             loc_line("A", dir, arg2, arg3)
  2410.          else
  2411.             loc_line("A", dir, arg3, arg4)
  2412.       }
  2413.       else if (argn == "FIND"   || argn == "FND" || argn == "F")
  2414.       {
  2415.          if (argn == arg1)
  2416.             loc_line("F", dir, arg2, arg3)
  2417.          else
  2418.             loc_line("F", dir, arg3, arg4)
  2419.       }
  2420.       else if (argn == "EXCLUDED" || argn == "EXC" || argn == "X")
  2421.          error("eXcluded line not supported")
  2422.       else
  2423.          error("Invalid parameters for LOCATE")
  2424.    }
  2425. }
  2426.  
  2427. local  function loc_line(what, dir, from, to)
  2428. {
  2429.    local ch
  2430.    local cmd
  2431.    local line
  2432.    local lineno
  2433.    local start_line
  2434.    local found_line
  2435.    local last_line
  2436.    local end_line
  2437.  
  2438.    if (argcount() >= 3 && from)
  2439.       start_line = find_label(from)
  2440.    else if (dir == "N")
  2441.       start_line = current_line + 1
  2442.    else
  2443.       start_line = 1
  2444.  
  2445.    if (argcount() >= 4 && to)
  2446.       end_line = find_label(to)
  2447.    else
  2448.       end_line = buffer_last_line
  2449.  
  2450.    for (line in line_command)
  2451.    {
  2452.       lineno = line+0
  2453.  
  2454.       if (lineno >= end_line)
  2455.          break
  2456.       else if (lineno >= start_line)
  2457.       {
  2458.          if (what == "A")
  2459.             found_line = line
  2460.          else
  2461.          {
  2462.             cmd = trim(ltrim(line_command[line]))
  2463.             ch  = substr(cmd,1,1)
  2464.    
  2465.             if (cmd == change_mark)
  2466.             {
  2467.                if (what == "C")
  2468.                   found_line = line
  2469.             }
  2470.             else if (cmd == find_mark)
  2471.             {
  2472.                if (what == "F")
  2473.                   found_line = line
  2474.             }
  2475.             else if (cmd == error_mark)
  2476.             {
  2477.                if (what == "E")
  2478.                   found_line = line
  2479.             }
  2480.             else if (ch == "=")
  2481.             {
  2482.                if (what == "S")
  2483.                   found_line = line
  2484.             }
  2485.             else if (ch == ".")
  2486.             {
  2487.                if (what == "L")
  2488.                   found_line = line
  2489.             }
  2490.             else
  2491.             {
  2492.                if (what == "M")
  2493.                   found_line = line
  2494.             }
  2495.          }
  2496.  
  2497.          if (found_line)
  2498.          {
  2499.             if (dir == "N" || dir == "F")
  2500.                break;
  2501.             else
  2502.             {
  2503.                if (dir == "reset")
  2504.                   delete_line_command(found_line)
  2505.                else
  2506.                   last_line = found_line
  2507.  
  2508.                found_line = ""
  2509.             }
  2510.          }
  2511.  
  2512.          if (dir == "P" && lineno >= current_line)
  2513.             break;
  2514.       }
  2515.    }
  2516.  
  2517.    if (dir == "N" || dir == "F")
  2518.    {
  2519.       if (found_line)
  2520.          goto_line(found_line)
  2521.       else
  2522.          error("Line not Located")
  2523.    }
  2524.    else if (dir != "reset")
  2525.    {
  2526.       if (last_line)
  2527.          goto_line(last_line)
  2528.       else
  2529.          error("Line not Located")
  2530.    }
  2531. }
  2532.  
  2533. global function ispf_reset(arg1, arg2, arg3)
  2534. {
  2535.    local fid = 0
  2536.  
  2537.    if (argcount() == 0)
  2538.      reset_line_commands(FALSE)
  2539.    else
  2540.    {
  2541.       arg1 = toupper(arg1)
  2542.  
  2543.       if (arg1 == "EXCLUDED" || arg1 == "EXC" || arg1 == "X")
  2544.          error("eXcluded lines not supported")
  2545.       else if (argcount() == 2 && (isdigit(arg1) || substr(arg1,1,1) == "."))
  2546.          loc_line("A", "reset", arg1, arg2)
  2547.       else
  2548.       {
  2549.          if (arg1 == "LABEL" || arg1 == "LAB" || arg1 == "L")
  2550.             fid = function_id("ispf:loc_line", "L", "reset", arg2, arg3)
  2551.          else if (arg1 == "COMMAND"  || arg1 == "CMD" || arg1 == "M")
  2552.             fid = function_id("ispf:loc_line", "M", "reset", arg2, arg3)
  2553.          else if (arg1 == "ERROR"    || arg1 == "ERR" || arg1 == "E")
  2554.             fid = function_id("ispf:loc_line", "E", "reset", arg2, arg3)
  2555.          else if (arg1 == "CHANGE"   || arg1 == "CHG" || arg1 == "C")
  2556.             fid = function_id("ispf:loc_line", "C", "reset", arg2, arg3)
  2557.          else if (arg1 == "SPECIAL"  || arg1 == "SPE" || arg1 == "S")
  2558.             fid = function_id("ispf:loc_line", "S", "reset", arg2, arg3)
  2559.          else if (arg1 == "ALL"      || arg1 == "A")
  2560.             reset_line_commands(TRUE)
  2561.          else
  2562.             error("Invalid parameters for RESET")
  2563.  
  2564.          if (fid)
  2565.          {
  2566.             if (argcount() > 1)
  2567.                reset_line_commands(FALSE, fid)
  2568.             else
  2569.                execute_function( fid )
  2570.          }
  2571.       }
  2572.    }
  2573. }
  2574.  
  2575. global function ispf_label(lptr, name)
  2576. {
  2577.    local label
  2578.  
  2579.    if (argcount() > 1)
  2580.    {
  2581.       label = toupper(ltrim(trim(name)))
  2582.  
  2583.       if (substr(label,1,1) == ".")
  2584.          line_command[find_label(lptr)] = label
  2585.       else
  2586.          error("Invalid label %s", name)
  2587.    }
  2588.    else if (argcount() > 0)
  2589.       label = line_command[find_label(lptr)]
  2590.  
  2591.    else
  2592.       error("Line not specified in a label request")
  2593.  
  2594.    return label
  2595. }
  2596.  
  2597. global function ispf_delete( arg1, arg2, arg3)
  2598. {
  2599.    local to
  2600.  
  2601.    if (toupper(arg1) == "ALL")
  2602.    {
  2603.       lc_line = find_label(arg2)
  2604.       to      = find_label(arg3)
  2605.    }
  2606.    else
  2607.    {
  2608.       lc_line = find_label(arg1)
  2609.       to      = find_label(arg2)
  2610.    }
  2611.  
  2612.    if (lc_line == 0)
  2613.        lc_line  = 1
  2614.  
  2615.    if (to)
  2616.       lc_arg = to - lc_line + 1
  2617.    else
  2618.       lc_arg = 1
  2619.  
  2620.    delete_lines() # simulate a delete lines line command.
  2621. }
  2622.  
  2623. global function ispf_recovery( on )
  2624. {
  2625.    on = toupper(on)
  2626.  
  2627.    if (!argcount() || on == "ON")
  2628.       autosave(autosave_time)
  2629.    else if (on == "OFF")
  2630.       autosave(0)
  2631.    else
  2632.       error("Invalid parameter %s for RECOVERY", on)
  2633. }
  2634.  
  2635. global function set_ispf_autosave( on )
  2636. {
  2637.    on = toupper(on)
  2638.  
  2639.    if (!argcount() || on == "ON")
  2640.       ispf_autosave = TRUE
  2641.    else if (on == "OFF")
  2642.       ispf_autosave = FALSE
  2643.    else
  2644.       error("Invalid parameter %s for AUTOSAVE", on)
  2645. }
  2646.  
  2647. global function set_ispf_tabs( on, dmy )
  2648. {
  2649.    on = toupper(on)
  2650.  
  2651.    if (!argcount() || on == "ON")
  2652.       ispf_tab_mode = FALSE
  2653.    else if (on == "OFF")
  2654.       ispf_tab_mode = TRUE
  2655.    else
  2656.       error("Invalid parameter %s for TABS", on)
  2657. }
  2658.  
  2659. global function set_ispf_caps( on )
  2660. {
  2661.    on = toupper(on)
  2662.  
  2663.    if (!argcount() || on == "ON")
  2664.       ispf_caps_mode = TRUE
  2665.    else if (on == "OFF")
  2666.       ispf_caps_mode = FALSE
  2667.    else
  2668.       error("Invalid parameter %s for CAPS", on)
  2669. }
  2670.  
  2671. global function set_ispf_hex( on )
  2672. {
  2673.    on = toupper(on)
  2674.  
  2675.    if (!argcount() || on == "ON" || on == "PC")
  2676.       toggle_dump_mode(TRUE)
  2677.    else if (on == "OFF")
  2678.       toggle_dump_mode(FALSE)
  2679.    else
  2680.       error("Invalid parameter %s for HEX", on)
  2681. }
  2682.  
  2683. global function ispf_fsplit()
  2684. {
  2685.    local cwindow
  2686.    local height
  2687.    local y1
  2688.  
  2689.    if( is_system_window())
  2690.       return
  2691.    else if (mdi_mode == 1 && !create_new_bufwin)
  2692.       switch_to_sdi()
  2693.    else if (mdi_mode)
  2694.    {
  2695.       cwindow = current_window
  2696.       height  = window_height
  2697.       if (cwindow != next_window())
  2698.       {
  2699.          height += window_height
  2700.          y1      = window_y0
  2701.          delete_window()
  2702.          current_window = cwindow
  2703.          frame_window(window_x0, window_y0 < y1 ? window_y0 : y1,
  2704.                       window_width, height)
  2705.       }
  2706.    }
  2707. }
  2708.  
  2709. global function ispf_split()
  2710. {
  2711.    local cwindow
  2712.    local amount
  2713.    local height
  2714.    local y0, y1
  2715.  
  2716.    if (is_system_window())
  2717.       return
  2718.  
  2719.    if (current_line <= window_first || \
  2720.        current_line >= window_first + window_text_height)
  2721.    {
  2722.       if (mdi_mode == 1 && !create_new_bufwin)
  2723.       {
  2724.          cwindow = current_window
  2725.          if (next_window() != cwindow && next_window() == cwindow)
  2726.          {
  2727.             switch_to_sdi() # if we have only 2 windows
  2728.             return
  2729.          }
  2730.       }
  2731.  
  2732.       if (mdi_mode)
  2733.       {
  2734.          cwindow = current_window
  2735.          height  = window_height
  2736.          if (next_window() != cwindow)
  2737.          {
  2738.             height += window_height
  2739.             y1      = window_y0
  2740.             delete_window()
  2741.             current_window = cwindow
  2742.             frame_window(window_x0, window_y0 < y1 ? window_y0 : y1,
  2743.                          window_width, height)
  2744.          }
  2745.       }
  2746.    }
  2747.    else
  2748.    {
  2749.       height = window_height - ((current_line - window_first) \
  2750.                                 * text_char_height)
  2751.       if (mdi_mode == 0)
  2752.       {
  2753.          switch_to_mdi()
  2754.          split_window_horizontal(height)
  2755.       }
  2756.       else
  2757.       {
  2758.          y0      = window_y0
  2759.          amount  = window_height / 2
  2760.  
  2761.          if (current_window == next_window())
  2762.             split_window_horizontal(height)
  2763.          else if( amount < WINDOW_MIN_HEIGHT * text_char_height)
  2764.          {
  2765.             if (mdi_mode == 1 && !create_new_bufwin)
  2766.                switch_to_sdi()
  2767.             else
  2768.             {
  2769.                cwindow = current_window
  2770.                height  = window_height
  2771.                if (next_window() != cwindow)
  2772.                {
  2773.                   height += window_height
  2774.                   y1      = window_y0
  2775.                   delete_window()
  2776.                   current_window = cwindow
  2777.                   frame_window(window_x0, window_y0 < y1 ? window_y0 : y1,
  2778.                                window_width, height)
  2779.                }
  2780.             }
  2781.          }
  2782.          else
  2783.          {
  2784.             # grow this window
  2785.             y1     = window_y0
  2786.             height = window_height + amount
  2787.  
  2788.             if (y1 > y0)
  2789.                frame_window( window_x0, y1 - amount, window_width, height )
  2790.             else
  2791.                frame_window( window_x0, y1, window_width, height )
  2792.  
  2793.             # shrink the other window
  2794.             prev_window()
  2795.             height  = window_height - amount
  2796.  
  2797.             if (y1 > y0)
  2798.                frame_window( window_x0, y0, window_width, amount )
  2799.             else
  2800.                frame_window( window_x0, y0 + amount, window_width, amount )
  2801.          }
  2802.       }
  2803.    }
  2804. }
  2805.  
  2806. global function ispf_swap(expand)
  2807. {
  2808.    if ( mdi_mode )
  2809.       next_window()
  2810.    else
  2811.       next_buffer()
  2812. }
  2813.  
  2814. global function ispf_close(cancel, exit_flag)
  2815. {
  2816.    local this_window = current_window
  2817.    local this_buffer = current_buffer
  2818.  
  2819.    if (buffer_is_modified())
  2820.    {
  2821.       if (argcount() && cancel)
  2822.          buffer_flags = and( buffer_flags, not( BUFFER_MODIFIED ) )
  2823.       else if (ispf_autosave)
  2824.          write_buffer()
  2825.    }
  2826.  
  2827.    if (mdi_mode == 2)
  2828.    {
  2829.       next_window()
  2830.       if (current_window != this_window)
  2831.       {
  2832.          current_window = this_window
  2833.          delete_window(this_window)
  2834.       }
  2835.       else if (argcount() >= 2 && exit_flag)
  2836.          quit(1,1)
  2837.       else
  2838.          delete_buffer(this_buffer)
  2839.    }
  2840.    else if ( mdi_mode == 1)
  2841.    {
  2842.       next_window()
  2843.       if (current_window != this_window)
  2844.       {
  2845.          current_window = this_window
  2846.          delete_window(this_window)
  2847.          this_window = current_window
  2848.          next_window()
  2849.          if (current_window != this_window)
  2850.          {
  2851.             current_window = this_window
  2852.             return
  2853.          }
  2854.       }
  2855.       else
  2856.       {
  2857.          next_buffer()
  2858.          if (current_buffer != this_buffer)
  2859.             delete_buffer(this_buffer)
  2860.       }
  2861.       switch_to_sdi()
  2862.    }
  2863.    else if (mdi_mode == 0)
  2864.    {
  2865.       if (argcount() >= 2 && exit_flag)
  2866.          quit(1,1)
  2867.       else
  2868.       {
  2869.          next_buffer()
  2870.          if (current_buffer != this_buffer)
  2871.             delete_buffer(this_buffer)
  2872.          else
  2873.             quit(1,1)
  2874.       }
  2875.    }
  2876. }
  2877.  
  2878. #
  2879. # EVENT.NEW_EMPTY_FILE Occured - Perform a Text Entry on the first line.
  2880. #
  2881. global function ispf_empty_file()
  2882. {
  2883.    lc_line = 0
  2884.    lc_arg  = 1
  2885.    ispf_text_entry()
  2886.    goto_line(1)
  2887. }
  2888.  
  2889. #
  2890. # EVENT.NEW_EDITFILE Occured - Save the initial state
  2891. #
  2892. global function ispf_new_file()
  2893. {
  2894.    new_edit_file()
  2895.    ispf_push_undo()
  2896. }
  2897.  
  2898. #
  2899. # EVENT.EMULATION_CHANGED Occured - ISPF Emulation is no longer active.
  2900. #
  2901. global function ispf_exit()
  2902. {
  2903.    reset_line_commands()
  2904.  
  2905.    find_mark   = ""                 # remove the find, error and change marks
  2906.    error_mark  = ""                 # for global searches
  2907.    change_mark = ""
  2908.  
  2909.    delete ispf_undo_stack           # delete ispf's undo stack
  2910.    delete ispf_undo_index
  2911.    delete ispf_last_index
  2912.  
  2913.    extended_quotes = FALSE          # Turn off extended quotes.
  2914.  
  2915.    ispf_fix_menu()                  # Fix any altered menuitems.
  2916.  
  2917.    toggle_linecommands( 0 )         # turn off line commands and
  2918.    default_linenumber_format  =     # restore line numbers to prev. state
  2919.    linenumber_format          = old_linenumber_format
  2920.  
  2921.    default_visible_end_buffer =     # Remove the END OF DATA line.
  2922.    visible_end_buffer         = ""
  2923.  
  2924.    setup_windows()                  # Reset all windows to new defaults.
  2925.  
  2926.    toggle_buffer_flags(BUFFER_OVERTYPE_MODE, insert_on )
  2927.  
  2928.    # delete event handlers
  2929.    delete_event(EVENT.EXIT_EDITOR,       "ispf_quit")
  2930.    delete_event(EVENT.NEW_EDIT_FILE,     "ispf_new_file")
  2931.    delete_event(EVENT.NEW_EMPTY_BUFFER,  "ispf_empty_file")
  2932.    delete_event(EVENT.EMULATION_CHANGED, "ispf_exit")
  2933.    delete_event(EVENT.TOOLBAR_COMMAND,   "ispexec")
  2934.    delete_event(EVENT.MENU_COMMAND,      "ispexec")
  2935. }
  2936.  
  2937. #
  2938. # EVENT.EXIT_EDITOR Occured - The editor is exiting.
  2939. #
  2940. global function ispf_quit()
  2941. {
  2942.    local start_buffer
  2943.    if (ispf_autosave)
  2944.    {
  2945.       for (start_buffer = 0; current_buffer != start_buffer;)
  2946.       {
  2947.          if (!start_buffer)
  2948.             start_buffer = current_buffer
  2949.          if (buffer_is_modified())
  2950.             write_buffer()
  2951.       }
  2952.    }
  2953. }
  2954.  
  2955. global function ispf_nyi()
  2956. {
  2957.    warning("ISPF function %s is not supported", lc_command)
  2958.    return LC_NOTOK
  2959. }
  2960.  
  2961. ################# ISPF SETTINGS NOTEBOOK PAGE ########################
  2962. global function create_ispf_page(dlgid)
  2963. {
  2964.    local dhIspfSettings = create_dialog(function_id( "ispf_settings_callback" ), 
  2965.                                         dlgid, IDD_ISPF_SETTINGS, resource_dll)
  2966.    attach_help(editor_helpfile, dhIspfSettings)
  2967.    initialize_ispf_settings( dhIspfSettings );
  2968.    begin_dialog(dhIspfSettings)
  2969. }
  2970.  
  2971. #
  2972. # ISPF Settings Notebook Page functions
  2973. #
  2974. local function initialize_ispf_settings( handle )
  2975. {
  2976.    set_dialog_item( handle, IDE_SCROLL_AMOUNT, DAC_EDIT_TEXT, ispf_scroll_amt "")
  2977.    
  2978.    if ( ispf_enter_mode )
  2979.    {
  2980.       set_dialog_item( handle, IDC_ENTER_MODE, DAC_CHECK)
  2981.       set_dialog_item( handle, IDC_CR_MODE, DAC_TEXT,
  2982.                        "3270 [Return] emulates ~PC Enter")
  2983.    }
  2984.    else
  2985.    {
  2986.       set_dialog_item( handle, IDC_ENTER_MODE, DAC_UNCHECK)
  2987.       set_dialog_item( handle, IDC_CR_MODE, DAC_TEXT,
  2988.                        "[Ctrl+Return] emulates ~PC Enter")
  2989.    }
  2990.  
  2991.    if ( ispf_cr_mode )
  2992.       set_dialog_item( handle, IDC_CR_MODE, DAC_CHECK)
  2993.    else
  2994.       set_dialog_item( handle, IDC_CR_MODE, DAC_UNCHECK)
  2995.  
  2996.    if ( ispf_home_mode )
  2997.    {
  2998.       set_dialog_item( handle, IDC_HOME_MODE, DAC_CHECK)
  2999.       set_dialog_item( handle, IDC_MOTION_MODE, DAC_TEXT,
  3000.                        "[Home] and [End] move to ~edge of window ONLY")
  3001.    }
  3002.    else
  3003.    {
  3004.       set_dialog_item( handle, IDC_HOME_MODE, DAC_UNCHECK)
  3005.       set_dialog_item( handle, IDC_MOTION_MODE, DAC_TEXT,
  3006.                        "[Num+5] and [End] move to ~edge of window ONLY")
  3007.    }
  3008.  
  3009.    if ( ispf_motion_mode )
  3010.       set_dialog_item( handle, IDC_MOTION_MODE, DAC_CHECK)
  3011.    else
  3012.       set_dialog_item( handle, IDC_MOTION_MODE, DAC_UNCHECK)
  3013.  
  3014.    if ( cursor_enters_linecommands )
  3015.       set_dialog_item( handle, IDC_CURSOR_MODE, DAC_CHECK)
  3016.    else
  3017.       set_dialog_item( handle, IDC_CURSOR_MODE, DAC_UNCHECK)
  3018.  
  3019.    if ( ispf_tab_mode )
  3020.       set_dialog_item( handle, IDC_TAB_MODE, DAC_CHECK)
  3021.    else
  3022.       set_dialog_item( handle, IDC_TAB_MODE, DAC_UNCHECK)
  3023.  
  3024.    if ( ispf_autosave )
  3025.       set_dialog_item( handle, IDC_ISPF_AUTOSAVE, DAC_CHECK)
  3026.    else
  3027.       set_dialog_item( handle, IDC_ISPF_AUTOSAVE, DAC_UNCHECK)
  3028. }
  3029.  
  3030. global function ispf_settings_callback()
  3031. {
  3032.    local handle = callback_dialog_handle
  3033.  
  3034.    if (callback_msg == DM_HELPREQUESTED)
  3035.    {
  3036.       if(isWindows())
  3037.          display_help("ISPF Settings", callback_dialog_handle);
  3038.       else
  3039.          display_help("ispfpage", callback_dialog_handle);
  3040.  
  3041.       return DRC_MSG_PROCESSED
  3042.    }
  3043.    else if((callback_msg == DM_CLICK) || (callback_msg == DM_DOUBLE_CLICK) )
  3044.    {
  3045.       if ( callback_index == IDC_ENTER_MODE)
  3046.       {
  3047.          if (query_dialog_item(handle, IDC_ENTER_MODE, DAC_CHECK))
  3048.             set_dialog_item( handle, IDC_CR_MODE, DAC_TEXT,
  3049.                              "3270 [Return] emulates ~PC Enter")
  3050.          else
  3051.             set_dialog_item( handle, IDC_CR_MODE, DAC_TEXT,
  3052.                              "[Ctrl+Return] emulates ~PC Enter")
  3053.          return DRC_MSG_PROCESSED
  3054.       }
  3055.       else if ( callback_index == IDC_HOME_MODE)
  3056.       {
  3057.          if (query_dialog_item(handle, IDC_HOME_MODE, DAC_CHECK))
  3058.             set_dialog_item( handle, IDC_MOTION_MODE, DAC_TEXT,
  3059.                              "[Home] and [End] move to ~edge of window ONLY")
  3060.          else
  3061.             set_dialog_item( handle, IDC_MOTION_MODE, DAC_TEXT,
  3062.                              "[Num+5] and [End] move to ~edge of window ONLY")
  3063.          return DRC_MSG_PROCESSED
  3064.       }
  3065.       else
  3066.          return DRC_CONTINUE
  3067.    }
  3068.    else if ( callback_msg == DM_CANCEL )
  3069.        return DRC_EXIT
  3070.    else if ( callback_msg == DM_OK )
  3071.    {
  3072.       assign_ispf_changes(handle)
  3073.       return DRC_EXIT     
  3074.    }
  3075.    else
  3076.       return DRC_CONTINUE
  3077. }
  3078.  
  3079.  
  3080. global function assign_ispf_changes(dlgid)
  3081. {
  3082.    ispf_scroll_amt  = toupper(query_dialog_item(dlgid, IDE_SCROLL_AMOUNT, DAC_EDIT_TEXT));
  3083.    ispf_enter_mode  =         query_dialog_item(dlgid, IDC_ENTER_MODE,    DAC_CHECK);
  3084.    ispf_cr_mode     =         query_dialog_item(dlgid, IDC_CR_MODE,       DAC_CHECK);
  3085.    ispf_tab_mode    =         query_dialog_item(dlgid, IDC_TAB_MODE,      DAC_CHECK);
  3086.    ispf_motion_mode =         query_dialog_item(dlgid, IDC_MOTION_MODE,   DAC_CHECK);
  3087.    ispf_autosave    =         query_dialog_item(dlgid, IDC_ISPF_AUTOSAVE, DAC_CHECK);
  3088.  
  3089.    cursor_enters_linecommands = query_dialog_item(dlgid, IDC_CURSOR_MODE, DAC_CHECK);
  3090.  
  3091.    if(query_dialog_item(dlgid, IDC_HOME_MODE, DAC_CHECK))
  3092.    {
  3093.       ispf_home_mode = TRUE;
  3094.       ispf_alter_menu();
  3095.    }
  3096. }
  3097.  
  3098. global function save_ispf_settings()
  3099. {
  3100.    local data_array
  3101.    local index = 0
  3102.  
  3103.    # if read_config_compiler is 1 then we haven't read the config
  3104.    # information in so don't try to write it just return.
  3105.    if (read_ispf_settings == 1)
  3106.       return data_array;
  3107.  
  3108.    data_array[ index++ ] = sprintf( "cursor_enters_linecommands=%d\n", cursor_enters_linecommands )
  3109.    data_array[ index++ ] = sprintf( "ispf_caps_mode=%d\n",             ispf_caps_mode )
  3110.    data_array[ index++ ] = sprintf( "ispf_scroll_amt=\"%s\"\n",        ispf_scroll_amt )
  3111.    data_array[ index++ ] = sprintf( "ispf_enter_mode=%d\n",            ispf_enter_mode )
  3112.    data_array[ index++ ] = sprintf( "ispf_cr_mode=%d\n",               ispf_cr_mode )
  3113.    data_array[ index++ ] = sprintf( "ispf_home_mode=%d\n",             ispf_home_mode )
  3114.    data_array[ index++ ] = sprintf( "ispf_motion_mode=%d\n",           ispf_motion_mode )
  3115.    data_array[ index++ ] = sprintf( "ispf_tab_mode=%d\n",              ispf_tab_mode )
  3116.    data_array[ index++ ] = sprintf( "ispf_autosave=%d\n",              ispf_autosave )
  3117.    data_array[ index++ ] = sprintf( "\n" )
  3118.    return data_array
  3119. }
  3120.