Jump to content

Customizing the Enhanced Editor: Difference between revisions

From EDM2
Formatting issues
Line 127: Line 127:
     Also MYKEYSET.E would not be included.</dd>
     Also MYKEYSET.E would not be included.</dd>


<p><dt>AUTOSAVE_PATH=''</dt>
<dt>AUTOSAVE_PATH=''</dt>
<dd>Specifies the path where "autosave" files will be
<dd>Specifies the path where "autosave" files will be
     placed.  The default value means that they're placed in the current
     placed.  The default value means that they're placed in the current
Line 133: Line 133:
     notebook.  The path specified there overrides the setting in MYCNF.E</dd>
     notebook.  The path specified there overrides the setting in MYCNF.E</dd>


<p><dt>BACKUP_PATH=''</dt>
<dt>BACKUP_PATH=''</dt>
<dd>Specifies the path setting for backup files.  Same as for
<dd>Specifies the path setting for backup files.  Same as for
     AUTOSAVE_PATH but there is no setting in the notebook for this one and it
     AUTOSAVE_PATH but there is no setting in the notebook for this one and it
Line 140: Line 140:
     must end with a backslash.</dd>
     must end with a backslash.</dd>


<p><dt>COMPILER_ERROR_COLOR=RED+WHITEB</dt>
<dt>COMPILER_ERROR_COLOR=RED+WHITEB</dt>
<dd>When used within the Workframe/2, EPM displays compiler errors.  This
<dd>When used within the Workframe/2, EPM displays compiler errors.  This
     constant is used to set the color used for the errors.  Default is red on
     constant is used to set the color used for the errors.  Default is red on
     white.  See <a HREF="#configcol">Configuring Colors</a></dd>
     white.  See <a HREF="#configcol">Configuring Colors</a></dd>


<p><a NAME="csyntaxassist">
<dt>C_SYNTAX_ASSIST=1</dt>
<dt>C_SYNTAX_ASSIST=1</dt>
<dd>Set this to 1 to include syntax assist for the C
<dd>Set this to 1 to include syntax assist for the C
Line 151: Line 150:
     corresponding language constructions.</dd>
     corresponding language constructions.</dd>


<p><a NAME="ctabs">
<dt>C_TABS=3</dt>
<dt>C_TABS=3</dt>
<dd>Specifies the default tab size for C files.</dd>
<dd>Specifies the default tab size for C files.</dd>


<p><dt>DEFAULT_PASTE=''</dt>
<dt>DEFAULT_PASTE=''</dt>
<dd>Use this setting to define the default behaviour of the
<dd>Use this setting to define the default behaviour of the
     paste key (Shift+Insert).  '' always pastes as new lines, 'B' pastes as a
     paste key (Shift+Insert).  '' always pastes as new lines, 'B' pastes as a
     block and 'C' pastes as a stream of characters.</dd>
     block and 'C' pastes as a stream of characters.</dd>


<p><dt>DRAG_ALWAYS_MARKS=0</dt>
<dt>DRAG_ALWAYS_MARKS=0</dt>
<dd>In advanced marking mode on dragging the mouse a new
<dd>In advanced marking mode on dragging the mouse a new
     block is only marked if there is no one currently marked.  This can be
     block is only marked if there is no one currently marked.  This can be
Line 168: Line 166:
     DRAG_ALWAYS_MARKS has no effect in CUA-marking mode.</dd>
     DRAG_ALWAYS_MARKS has no effect in CUA-marking mode.</dd>


<p><dt>ENHANCED_ENTER_KEYS=0</dt>
<dt>ENHANCED_ENTER_KEYS=0</dt>
<dd>Set this one to 1 to be able to set the action
<dd>Set this one to 1 to be able to set the action
     performed by the Enter keys with EPMs settings notebook.  Using the default
     performed by the Enter keys with EPMs settings notebook.  Using the default
Line 174: Line 172:
     C_ENTER_ACTION, see EPM Users Guide).</dd>
     C_ENTER_ACTION, see EPM Users Guide).</dd>


<p><dt>ENHANCED_PRINT_SUPPORT=0</dt>
<dt>ENHANCED_PRINT_SUPPORT=0</dt>
<dd>Set this to 1 to tell EPM to bring up the
<dd>Set this to 1 to tell EPM to bring up the
     "Print" dialog when you specify the print command from the menu instead of
     "Print" dialog when you specify the print command from the menu instead of
     just printing the file.</dd>
     just printing the file.</dd>


<p><dt>EPATH='EPMPATH'</dt>
<dt>EPATH='EPMPATH'</dt>


<dd>Specifies the environment variable used to store EPM's
<dd>Specifies the environment variable used to store EPM's
     search path.</dd>
     search path.</dd>


<p><dt>EXTRA_EX=0</dt>
<dt>EXTRA_EX=0</dt>
<dd>This must be set to 1. Code size for .EX-files is limited to
<dd>This must be set to 1. Code size for .EX-files is limited to
     64K, which is too small for the standard configuration.  If EXTRA_EX is set
     64K, which is too small for the standard configuration.  If EXTRA_EX is set
Line 190: Line 188:
     loaded on startup.</dd>
     loaded on startup.</dd>


<p><dt>E_SYNTAX_ASSIST=1</dt>
<dt>E_SYNTAX_ASSIST=1</dt>
<dd>Enables syntax assist for the E language.  See
<dd>Enables syntax assist for the E language.  See
     <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.</dd>
     <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.</dd>


<p><dt>E_TABS=3</dt>
<dt>E_TABS=3</dt>


<dd>Sets the default tab setting for .E files.  See <a HREF="#ctabs">C_TABS</a>.</dd>
<dd>Sets the default tab setting for .E files.  See <a HREF="#ctabs">C_TABS</a>.</dd>


<p><dt>HELPFILENAME='epmhelp.qhl'</dt>
<dt>HELPFILENAME='epmhelp.qhl'</dt>
<dd>Sets the filename for the "Quick Help" file.</dd>
<dd>Sets the filename for the "Quick Help" file.</dd>


<p><dt>HIGHLIGHT_COLOR=</dt>
<dt>HIGHLIGHT_COLOR=</dt>
<dd>Sets the color that is used to draw these fancy circles
<dd>Sets the color that is used to draw these fancy circles
     around found search strings.  There is no default so you have to specify
     around found search strings.  There is no default so you have to specify
     it.  See <a HREF="#configcol">Configuring Colors</a></dd>
     it.  See <a HREF="#configcol">Configuring Colors</a></dd>


<p><dt>INCLUDE_WORKFRAME_SUPPORT=1</dt>
<dt>INCLUDE_WORKFRAME_SUPPORT=1</dt>


<dd>Specifies if support for IBM WorkFrame/2 is
<dd>Specifies if support for IBM WorkFrame/2 is
     included in the configuration.</dd>
     included in the configuration.</dd>


<p><dt>MARKCOLOR=Blue+GreyB</dt>
<dt>MARKCOLOR=Blue+GreyB</dt>
<dd>Sets the color used to mark marked marks in your
<dd>Sets the color used to mark marked marks in your
     file.  See <a HREF="#configcol">Configuring Colors</a></dd>
     file.  See <a HREF="#configcol">Configuring Colors</a></dd>


<p><dt>MENU_LIMIT=0</dt>
<dt>MENU_LIMIT=0</dt>
<dd>You can edit several files in one EPM window using the file
<dd>You can edit several files in one EPM window using the file
     ring.  Usually these files can be accessed with the Ring menu command which
     ring.  Usually these files can be accessed with the Ring menu command which
Line 224: Line 222:
     makes no sense.</dd>
     makes no sense.</dd>


<p><dt>MESSAGECOLOR=Light_Red+WhiteB</dt>
<dt>MESSAGECOLOR=Light_Red+WhiteB</dt>
<dd>Sets the color used to display the message
<dd>Sets the color used to display the message
     line or error messages.  See <a HREF="#configcol">Configuring Colors</a></dd>
     line or error messages.  See <a HREF="#configcol">Configuring Colors</a></dd>


<p><dt>MY_DEFAULT_EDIT_OPTIONS=''</dt>
<dt>MY_DEFAULT_EDIT_OPTIONS=''</dt>
<dd>Set default options for the edit command.
<dd>Set default options for the edit command.
     These default options will be overridden by options specified on each
     These default options will be overridden by options specified on each
     specific edit command.</dd>
     specific edit command.</dd>


<p><dt>MY_DEFAULT_SAVE_OPTIONS=''</dt>
<dt>MY_DEFAULT_SAVE_OPTIONS=''</dt>
<dd>Same as MY_DEFAULT_EDIT_OPTIONS for the save command.</dd>
<dd>Same as MY_DEFAULT_EDIT_OPTIONS for the save command.</dd>


<p><dt>MY_DEFAULT_SEARCH_OPTIONS=''</dt>
<dt>MY_DEFAULT_SEARCH_OPTIONS=''</dt>
<dd>Another one, this time for search commands!</dd>
<dd>Another one, this time for search commands!</dd>


<p><dt>MY_SAVE_WITH_TABS=0</dt>
<dt>MY_SAVE_WITH_TABS=0</dt>


<dd>Set this to 1 to tell EPM to automatically compresses
<dd>Set this to 1 to tell EPM to automatically compresses
Line 245: Line 243:
     MY_DEFAULT_SAVE_OPTIONS.</dd>
     MY_DEFAULT_SAVE_OPTIONS.</dd>


<p><dt>NLS_LANGUAGE='english'</dt>
<dt>NLS_LANGUAGE='english'</dt>
<dd>Sets the language for National Language Support.</dd>
<dd>Sets the language for National Language Support.</dd>


<p><dt>P_SYNTAX_ASSIST=1</dt>
<dt>P_SYNTAX_ASSIST=1</dt>
<dd>Includes Pascal syntax assist. See <a
<dd>Includes Pascal syntax assist. See <a
     HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.</dd>
     HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.</dd>


<p><dt>P_TABS=3</dt>
<dt>P_TABS=3</dt>


<dd>Sets the tab size for Pascal files. See <a HREF="#ctabs">C_TABS</a>.</dd>
<dd>Sets the tab size for Pascal files. See <a HREF="#ctabs">C_TABS</a>.</dd>


<p><dt>REXX_SYNTAX_ASSIST=1</dt>
<dt>REXX_SYNTAX_ASSIST=1</dt>
<dd>Includes REXX syntax assist. See <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.</dd>
<dd>Includes REXX syntax assist. See <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.</dd>


<p><dt>REXX_TABS=3</dt>
<dt>REXX_TABS=3</dt>
<dd>Sets the tab size for REXX files. See <a HREF="#ctabs">C_TABS</a>.</dd>
<dd>Sets the tab size for REXX files. See <a HREF="#ctabs">C_TABS</a>.</dd>


<p><dt>SETSTAY=0</dt>
<dt>SETSTAY=0</dt>
<dd>This option controls where the cursor is located after a change
<dd>This option controls where the cursor is located after a change
     command. 0 means it is located on the last changed string, 1 means it stays
     command. 0 means it is located on the last changed string, 1 means it stays
Line 268: Line 266:
     this behavior.</dd>
     this behavior.</dd>


<p><dt>STATUS_TEMPLATE='Line %l of %s  Column %c  %i  %m  %f'</dt>
<dt>STATUS_TEMPLATE='Line %l of %s  Column %c  %i  %m  %f'</dt>
<dd>This is the status
<dd>This is the status
     string used to configure the status line.  The template can be up to 128
     string used to configure the status line.  The template can be up to 128
Line 286: Line 284:
     </small></pre></dd>
     </small></pre></dd>


<p><dt>SUPPORT_TECHREF=0</dt>
<dt>SUPPORT_TECHREF=0</dt>
<dd>Set this to 1 to add a 'View Technical Reference'
<dd>Set this to 1 to add a 'View Technical Reference'
     command to the help menu.</dd>
     command to the help menu.</dd>


<p><dt>SUPPORT_USERS_GUIDE=0</dt>
<dt>SUPPORT_USERS_GUIDE=0</dt>
<dd>Set this to 1 to add a 'View Users Guide' command
<dd>Set this to 1 to add a 'View Users Guide' command
     to the help menu.</dd>
     to the help menu.</dd>


<p><dt>SUPPORT_USER_EXITS=0</dt>
<dt>SUPPORT_USER_EXITS=0</dt>
<dd>User Exits are procedures that are called by certain
<dd>User Exits are procedures that are called by certain
     command, e.g. load and save.  Setting SUPPORT_USER_EXITS to 1 enables this
     command, e.g. load and save.  Setting SUPPORT_USER_EXITS to 1 enables this
     feature.  See <a HREF="#yourowncomandproc">Your own commands and procedures via MYSTUFF.E</a></dd>
     feature.  See <a HREF="#yourowncomandproc">Your own commands and procedures via MYSTUFF.E</a></dd>


<p><dt>SYNTAX_INDENT='3'</dt>
<dt>SYNTAX_INDENT='3'</dt>
<dd>Specifies the number of spaces used for syntax indent
<dd>Specifies the number of spaces used for syntax indent
     when syntax assist is used.</dd>
     when syntax assist is used.</dd>


<p><dt>TEXTCOLOR=Black+WhiteB</dt>
<dt>TEXTCOLOR=Black+WhiteB</dt>
<dd>Specifies the color used to display normal
<dd>Specifies the color used to display normal
     unmarked text in the edit window.  See <a HREF="#configcol">Configuring Colors</a></dd>
     unmarked text in the edit window.  See <a HREF="#configcol">Configuring Colors</a></dd>


<p><dt>TOGGLE_ESCAPE=0</dt>
<dt>TOGGLE_ESCAPE=0</dt>
<dd>Set this to 1 to define the ESCAPEKEY command.</dd>
<dd>Set this to 1 to define the ESCAPEKEY command.</dd>


<p><dt>TOGGLE_TAB=0</dt>
<dt>TOGGLE_TAB=0</dt>
<dd>Set this to 1 to define the TABKEY command.</dd>
<dd>Set this to 1 to define the TABKEY command.</dd>


<p><dt>TRASH_TEMP_FILES=0</dt>
<dt>TRASH_TEMP_FILES=0</dt>


<dd>If set to 1 temporary files (which begin with a '.')
<dd>If set to 1 temporary files (which begin with a '.')
Line 320: Line 318:
     the '.ALL' file upon exit).</dd>
     the '.ALL' file upon exit).</dd>


<p><dt>UNDERLINE_CURSOR=0</dt>
<dt>UNDERLINE_CURSOR=0</dt>
<dd>Specifies the style of the cursor used in the editor.
<dd>Specifies the style of the cursor used in the editor.
     Default is a vertical bar in front of the actual character.  Set to 1
     Default is a vertical bar in front of the actual character.  Set to 1
     changes it to a horizontal bar below the actual character.</dd>
     changes it to a horizontal bar below the actual character.</dd>


<p><dt>UNMARK_AFTER_MOVE=0</dt>
<dt>UNMARK_AFTER_MOVE=0</dt>
<dd>Use this switch if you want marked text to be
<dd>Use this switch if you want marked text to be
     unmarked after a move operation.  Default is that it is not.</dd>
     unmarked after a move operation.  Default is that it is not.</dd>


<p><dt>USE_APPEND=0</dt>
<dt>USE_APPEND=0</dt>
<dd>Set this to 1 to make EPM search for files along DPATH if
<dd>Set this to 1 to make EPM search for files along DPATH if
     they can't be found in the current directory.</dd>
     they can't be found in the current directory.</dd>


<p><dt>WANT_ALL=0</dt>
<dt>WANT_ALL=0</dt>
<dd>Set this to 1 to include the ALL command.</dd>
<dd>Set this to 1 to include the ALL command.</dd>


<p><dt>WANT_BOOKMARKS='LINK'</dt>
<dt>WANT_BOOKMARKS='LINK'</dt>
<dd>Specifies whether or not bookmark support is
<dd>Specifies whether or not bookmark support is
     included.  The default is that bookmark support is linked at runtime (or
     included.  The default is that bookmark support is linked at runtime (or
     included in EXTRA.EX if this is used).</dd>
     included in EXTRA.EX if this is used).</dd>


<p><dt>WANT_CHAR_OPS=1</dt>
<dt>WANT_CHAR_OPS=1</dt>
<dd>Set this to 0 to disable character marking mode support.</dd>
<dd>Set this to 0 to disable character marking mode support.</dd>


<p><dt>WANT_CUA_MARKING=0</dt>
<dt>WANT_CUA_MARKING=0</dt>


<dd>Set this to 1 to use the CUA marking style instead of
<dd>Set this to 1 to use the CUA marking style instead of
Line 350: Line 348:
     Preferences menu.</dd>
     Preferences menu.</dd>


<p><dt>WANT_DRAW='F6'</dt>
<dt>WANT_DRAW='F6'</dt>
<dd>Includes the DRAW command.  Default is to include it and
<dd>Includes the DRAW command.  Default is to include it and
     define the 'F6' key for it.  Other options are 1 and 0.</dd>
     define the 'F6' key for it.  Other options are 1 and 0.</dd>


<p><dt>WANT_DYNAMIC_PROMPTS=1</dt>
<dt>WANT_DYNAMIC_PROMPTS=1</dt>
<dd>Includes dynamic prompt support.  If it is
<dd>Includes dynamic prompt support.  If it is
     included (default) there is a Prompting option in the Frame Controls menu.
     included (default) there is a Prompting option in the Frame Controls menu.
Line 360: Line 358:
     message line.</dd>
     message line.</dd>


<p><dt>WANT_ET_COMMAND=1</dt>
<dt>WANT_ET_COMMAND=1</dt>
<dd>Includes the ET command to issue ETPM from EPM.</dd>
<dd>Includes the ET command to issue ETPM from EPM.</dd>


<p><dt>WANT_KEYBOARD_HELP=0</dt>
<dt>WANT_KEYBOARD_HELP=0</dt>
<dd>If keyboard help is activated the CTRL-H key is
<dd>If keyboard help is activated the CTRL-H key is
     redefined to issue a keyword help procedure that looks through the files
     redefined to issue a keyword help procedure that looks through the files
Line 370: Line 368:
     .NDX-file, usually by invoking VIEW.EXE.</dd>
     .NDX-file, usually by invoking VIEW.EXE.</dd>


<p><dt>WANT_LONGNAMES=0</dt>
<dt>WANT_LONGNAMES=0</dt>
<dd>Includes support for long names.  A value of SWITCH
<dd>Includes support for long names.  A value of SWITCH
     defines a Longnames command.</dd>
     defines a Longnames command.</dd>


<p><dt>WANT_PROFILE=0</dt>
<dt>WANT_PROFILE=0</dt>
<dd>Includes support for a REXX profile.  If profile support
<dd>Includes support for a REXX profile.  If profile support
     is included EPM looks for a file called PROFILE.ERX upon startup and
     is included EPM looks for a file called PROFILE.ERX upon startup and
     executes it if found. A value of SWITCH defines the Profile command.</dd>
     executes it if found. A value of SWITCH defines the Profile command.</dd>


<p><dt>WANT_STACK_CMDS=0</dt>
<dt>WANT_STACK_CMDS=0</dt>


<dd>Includes a set of stack commands.  The commands are
<dd>Includes a set of stack commands.  The commands are
Line 386: Line 384:
     defines an entry in the Preferencs menu.</dd>
     defines an entry in the Preferencs menu.</dd>


<p><dt>WANT_STREAM_MODE=0</dt>
<dt>WANT_STREAM_MODE=0</dt>
<dd>Set this to 1 to make EPM use a stream mode approach
<dd>Set this to 1 to make EPM use a stream mode approach
     to file editing that is the edited file is seen as a continuing stream of
     to file editing that is the edited file is seen as a continuing stream of
Line 395: Line 393:


See Example MYCNF.E
See Example MYCNF.E
<a NAME="configcol">


== Configuring Colors ==
== Configuring Colors ==
Line 403: Line 399:
used within EPM macros.  The available constants are:
used within EPM macros.  The available constants are:


<p><table BORDER=1 CELLPADDING=3>
<table BORDER=1 CELLPADDING=3>
<tr><td COLSPAN=2><b>Foreground Colors</b></td><td COLSPAN=2><b>Background Colors</b></td></tr>
<tr><td COLSPAN=2><b>Foreground Colors</b></td><td COLSPAN=2><b>Background Colors</b></td></tr>


Line 628: Line 624:
Select this to go to the next section
Select this to go to the next section


<a NAME="yourowncomandproc">
== Your own commands and procedures via MYSTUFF.E ==
== Your own commands and procedures via MYSTUFF.E ==


Line 680: Line 675:
MYSTUFF.E:
MYSTUFF.E:


<pre><small>
include 'saveall.e'
include 'saveall.e'
 
defc gocol
defc gocol
    .col = arg(1)
    .col = arg(1)
 
/* For the autoload feature we maintain a list of
/* For the autoload feature we maintain a list of
the currently open files in a profile entry named
the currently open files in a profile entry named
STARTUP_FILES. The first one is the file actually
STARTUP_FILES. The first one is the file actually
edited to make sure it comes up on restart */
edited to make sure it comes up on restart */
 
/* This one makes sure that the file that was on
/* This one makes sure that the file that was on
top on shutdown will reappear there on startup.
top on shutdown will reappear there on startup.
Defselects are called whenever a file is selected */
Defselects are called whenever a file is selected */
 
defselect
defselect
 
    /* The application name and INI-handle
  /* The application name and INI-handle
    are stored in these global variables */
  are stored in these global variables */
 
    universal appname, app_hini
  universal appname, app_hini
 
    -- Save cursor position
  -- Save cursor position
    psave_pos(spos)
  psave_pos(spos)
 
    -- get actual filelist
  -- get actual filelist
    filelist = queryprofile( $HINI_PARM appname,
  filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')
                            'STARTUP_FILES')
 
    -- find actual file
  -- find actual file
    if wordpos(.filename, filelist) then
  if wordpos(.filename, filelist) then
 
      -- and remove it
      -- and remove it
      filelist = delword(filelist,
      filelist = delword(filelist,
                          wordpos(.filename,filelist),1)
                        wordpos(.filename,filelist),1)
 
    endif
  endif
 
    if (not wordpos(.filename, filelist)) and
  if (not wordpos(.filename, filelist)) and
      (substr(.filename, lastpos('\', .filename)
      (substr(.filename, lastpos('\', .filename)
      + 1, 1) &lt;&gt; '.') then
      + 1, 1) &lt;&gt; '.') then
 
        -- add the actual filename at the beginning
      -- add the actual filename at the beginning
        filelist = .filename' 'filelist
      filelist = .filename' 'filelist
 
    endif
  endif
 
    -- write the new list to the INI-file
  -- write the new list to the INI-file
    setprofile( $HINI_PARM appname, 'STARTUP_FILES',
  setprofile( $HINI_PARM appname, 'STARTUP_FILES',
                filelist )
              filelist )
 
    -- Restore cursor position
  -- Restore cursor position
    prestore_pos(spos)
  prestore_pos(spos)
 
-- called just after file was saved
-- called just after file was saved
defproc postsave_exit (fname)
defproc postsave_exit (fname)
 
    /* oldfile is the old filename
  /* oldfile is the old filename
    if file was renamed */
  if file was renamed */
 
    universal appname, app_hini, oldfile
  universal appname, app_hini, oldfile
 
    -- Save cursor position
  -- Save cursor position
    psave_pos(spos)
  psave_pos(spos)
 
    -- get the old file list
  -- get the old file list
    filelist = queryprofile( $HINI_PARM appname,
  filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')
                            'STARTUP_FILES')
 
    -- if old filename is in the list
  -- if old filename is in the list
    if wordpos(oldfile, filelist) then
  if wordpos(oldfile, filelist) then
 
        -- delete it
      -- delete it
        filelist = delword(filelist,
                          wordpos(oldfile,filelist),1)
    endif
    if (not wordpos(fname, filelist)) and
      (substr(fname, lastpos('\', fname)
      + 1,1) &lt;&gt; '.') then
        -- Add actual filename if its not
        -- a tempfile ('.---')
        filelist = fname' 'filelist
        -- remove the 'and (substr...' section if
        -- you want to restart temp files
    endif
    -- store the new list
    setprofile( $HINI_PARM appname,
                'STARTUP_FILES', filelist )
    -- Restore cursor position
    prestore_pos(spos)
  -- called if file was renamed
  defproc rename_exit (oldfile, fname)
    universal appname, app_hini
    -- Save cursor position
    psave_pos(spos)
    -- same as for postsave_exit
    filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')
    if wordpos(oldfile, filelist) then
       filelist = delword(filelist,
       filelist = delword(filelist,
                           wordpos(oldfile,filelist),1)
                           wordpos(oldfile,filelist),1)
 
  endif
    endif
 
  if (not wordpos(fname, filelist)) and
    if (not wordpos(fname, filelist)) and
      (substr(fname, lastpos('\', fname)
      (substr(fname, lastpos('\', fname)
      + 1,1) &lt;&gt; '.') then
       + 1, 1) &lt;&gt; '.') then
 
       -- Add actual filename if its not
        filelist = fname' 'filelist
      -- a tempfile ('.---')
      filelist = fname' 'filelist
    endif
 
      -- remove the 'and (substr...' section if
    setprofile( $HINI_PARM appname,
      -- you want to restart temp files
                'STARTUP_FILES', filelist )
 
  endif
    -- Restore cursor position
 
    prestore_pos(spos)
  -- store the new list
  setprofile( $HINI_PARM appname,
-- called if file is closed
              'STARTUP_FILES', filelist )
defproc quit_exit (fname)
 
  -- Restore cursor position
    universal appname, app_hini
  prestore_pos(spos)
 
    -- just delete entry
-- called if file was renamed
    filelist = queryprofile( $HINI_PARM appname,
defproc rename_exit (oldfile, fname)
                            'STARTUP_FILES')
 
  universal appname, app_hini
    if wordpos(fname, filelist) then
 
      filelist = delword(filelist,
  -- Save cursor position
                          wordpos(fname,filelist),1)
  psave_pos(spos)
 
    endif
  -- same as for postsave_exit
  filelist = queryprofile( $HINI_PARM appname,
    setprofile( $HINI_PARM appname,
                            'STARTUP_FILES')
                'STARTUP_FILES', filelist )
 
  if wordpos(oldfile, filelist) then
-- Defload functions are called whenever a file was loaded
      filelist = delword(filelist,
                        wordpos(oldfile,filelist),1)
defload        /* same as for namefile and savefile,
 
                just that there are no old names to
  endif
                delete */
 
  if (not wordpos(fname, filelist)) and
    universal appname, app_hini
      (substr(fname, lastpos('\', fname)
    filelist = queryprofile( $HINI_PARM appname,
      + 1, 1) &lt;&gt; '.') then
                            'STARTUP_FILES')
 
      filelist = fname' 'filelist
    if (not wordpos(.filename, filelist)) and
 
      (substr(.filename, lastpos('\', .filename)
  endif
      + 1, 1) &lt;&gt; '.') then
 
  setprofile( $HINI_PARM appname,
        filelist = .filename' 'filelist
              'STARTUP_FILES', filelist )
 
  -- Restore cursor position
  prestore_pos(spos)
 
-- called if file is closed
defproc quit_exit (fname)
 
  universal appname, app_hini
 
  -- just delete entry
  filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')
 
  if wordpos(fname, filelist) then
      filelist = delword(filelist,
                        wordpos(fname,filelist),1)
 
  endif
 
  setprofile( $HINI_PARM appname,
              'STARTUP_FILES', filelist )
 
-- Defload functions are called whenever a file was loaded
 
defload        /* same as for namefile and savefile,
              just that there are no old names to
              delete */
 
  universal appname, app_hini
  filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')
 
  if (not wordpos(.filename, filelist)) and
      (substr(.filename, lastpos('\', .filename)
      + 1, 1) &lt;&gt; '.') then
 
      filelist = .filename' 'filelist
 
  endif
 
  setprofile( $HINI_PARM appname,
              'STARTUP_FILES', filelist )
 
/* Here comes the Cursor position feature */
 
-- issued just before a file is saved
defproc presave_exit
 
  -- used to store the filename for postsave_exit
  universal oldfile
 
  -- delete old 'EPM.POS' entry in the EAs
  delete_ea('EPM.POS')
 
  -- get cursor and screen position,...
  psave_pos(screenpos)
 
  -- and store it in the EA
  'addea EPM.POS' screenpos
 
  -- this one's needed for the restart feature
  oldfile = .filename
 
-- This one's for setting the Cursor and window
--position for the loaded file
defload
 
    if find_ea('EPM.POS', ea_seg, ea_ofs, ea_ptr1,
      ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
 
        -- if there's an EPM.POS EA...
 
        -- that's the actual file
        getfileid myid
 
        'postme restore_ORG_pos
        'myid get_EAT_ASCII_value('EPM.POS')
 
        /* restore postions. have to post it 'cause
        the screen may not yet be painted. Also I
        had to make this the last of my defloads to
        make it work correctly */
 
     endif
     endif
 
-- This sets the cursor and screen-positions.
    setprofile( $HINI_PARM appname,
-- It does the same as
                'STARTUP_FILES', filelist )
defc restore_ORG_pos
 
/* Here comes the Cursor position feature */
        -- prestore_pos except for being passed
        -- the fileid as first parameter
-- issued just before a file is saved
 
defproc presave_exit
        parse value arg(1) with myid fline fcol cx cy
        myid.cursorx = cx
    -- used to store the filename for postsave_exit
        myid.cursory = cy
    universal oldfile
        myid.line = fline
        myid.col = fcol
    -- delete old 'EPM.POS' entry in the EAs
</small></pre>
    delete_ea('EPM.POS')
 
    -- get cursor and screen position,...
    psave_pos(screenpos)
    -- and store it in the EA
    'addea EPM.POS' screenpos
    -- this one's needed for the restart feature
    oldfile = .filename
-- This one's for setting the Cursor and window
--position for the loaded file
defload
    if find_ea('EPM.POS', ea_seg, ea_ofs, ea_ptr1,
        ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
        -- if there's an EPM.POS EA...
        -- that's the actual file
        getfileid myid
        'postme restore_ORG_pos
        'myid get_EAT_ASCII_value('EPM.POS')
          /* restore postions. have to post it 'cause
          the screen may not yet be painted. Also I
          had to make this the last of my defloads to
          make it work correctly */
    endif
-- This sets the cursor and screen-positions.
-- It does the same as
defc restore_ORG_pos
        -- prestore_pos except for being passed
        -- the fileid as first parameter
        parse value arg(1) with myid fline fcol cx cy
        myid.cursorx = cx
        myid.cursory = cy
        myid.line = fline
        myid.col = fcol
MAINEXIT.E:
MAINEXIT.E:


<pre><small>
define
-- 5.20 adds a HINI to the *Profile calls.
compile if EVERSION >= '5.20'
  HINI_PARM = 'app_hini,'
compile else
  HINI_PARM = ' '
compile endif
-- called just before files are loaded upon startup
defproc defmain_exit (var cmdline)
  universal appname, app_hini
  -- this is the command line + 'e '.
  -- If no parameters are specified ...
  if cmdline = 'e ' then
      -- ...add the ones from 'STARTUP_FILES'
      cmdline ='e 'queryprofile( $HINI_PARM appname,
                                  'STARTUP_FILES' )
  endif
</small></pre>


define
-- 5.20 adds a HINI to the *Profile calls.
compile if EVERSION >= '5.20'
    HINI_PARM = 'app_hini,'
compile else
    HINI_PARM = ' '
compile endif
-- called just before files are loaded upon startup
defproc defmain_exit (var cmdline)
    universal appname, app_hini
    -- this is the command line + 'e '.
    -- If no parameters are specified ...
    if cmdline = 'e ' then
        -- ...add the ones from 'STARTUP_FILES'
        cmdline ='e 'queryprofile( $HINI_PARM appname,
                                  'STARTUP_FILES' )
    endif
== Editor startup code via MYMAIN.E ==
== Editor startup code via MYMAIN.E ==



Revision as of 05:16, 21 February 2005

Written by Jörg Schwieder

Introduction

If you talk with OS/2 developers, you will soon get the impression that most of them are desperately looking for a good programming editor even though OS/2 includes EPM, a very capable and flexible editor. One of the reasons for the bad reputation EPM seems to have may be its standard configuration which makes it resemble the system editor, OS/2's version of the Windows Notepad. Another reason may be that - though it is very flexible - it shares the problem of a lot of software that was 'born to use': that is it was written to be used not to be sold or that evolved from a line of more simple product improved over the time. Its user-interface clearly shows some of the author's preferences and remainders from former stages of development. For example, this means that EPM is almost completely incapable of using 'hard' tabs (which doesn't matter if you don't like them but if you're used to using such features it is quite a drawback).

So if you want to use EPM you may need to customize it. To do this you need the complete EPM toolkit available on various ftp sites such as cdrom.com. It includes an updated (and reconfigured) version of EPM along with a better documentation and a compiler for the E macro language (ETPM). This article will cover custom configuration of your editor using this toolkit and - through examples - provide you with some nice additional features such as file autoloading and positioning and keyboard undo.

The EPM Programming Model

Programming EPM

There are two ways of programming EPM: using REXX and using the E macro language. Using REXX you may write EPM macros that don't need to be compiled and you don't have to learn the E macro language. This is quite powerful and lets you use most of EPM's features including custem menus, etc. and so it may be great for user macros but you cannot change the default configuration using REXX and since its interpreted and not compiled its quite slow so we will use the macro language here.

What is EPM?

EPM is not a "program" as such. The key element of the editor is the Enhanced Multi-Line Edit control (E-MLE) that is defined if the E-Toolkit (ETK) DLL's. It may also be used in custom programs (see the ETK documentation). Most of the basic functionality as well as macro language and REXX support are provided by the control. It can be used to edit multiple files in a "ring" which may be as large as system memory permits. EPM itself is just a small program that manages E-MLEs and the user interface (e.g. dialogs).

The Macro Language

Most of the features that make EPM were added using the E macro language and therefore may be rewritten or changed as well as used within other programs. For example, it would be possible to write applications using E-MLEs for their own editing purpose but incorporating the user's individual EPM setup. Given its capability to use the REXX language this makes for a great shot in the way of finding an individual standard user interface (a paradox within conventional application design).

Okay, let's get back to EPM. Macros that were written using the macro language (*.E) are compiled with the macro compiler ETPM and become ETPM modules (*.EX). An E-MLE has one main module (EPM.EX for EPM) which is executed upon creation and which contains startup and close-down code as well as basic functions and commands, menus, key-definitions etc. There may be additional modules that define external commands, they can be executed at runtime or linked into a running system meaning they're loaded permanently.

The macro language itself closely resembles REXX with some compiler specific differences especially regarding variable handling. See the EPM Technical Reference included in the complete EPM distribution.

Changing Your Configuration

The EPM main module is called EPM.E. (Well, in fact EPM.E currently does nothing else than including E.E which is the real main module but in the documentation the main module is said to be EPM.E so we call it that.) It includes the other EPM modules and is compiled to EPM.EX. Changes to the default configuration have to be recognized by EPM.E; usually this is done by changing a set of files that are included in EPM.E: MYCNF.E, MYKEYS.E, MYSTUFF.E, MYMAIN.E, MYSELECT.E and MYKEYSET.E.

MYCNF.E is a configuration file you should use to set configuration switches whereas the other ones are thought to include code. You may recompile your standard configuration by just recompiling EPM.E.

  • Changing the default configuration via MYCNF.E
  • Adding your own key definitions via MYKEYS.E
  • Your own commands and procedures via MYSTUFF.E
  • Editor startup code via MYMAIN.E
  • File initializations and focus changes via MYSELECT.E

You should use MYKEYSET.E to define a whole new keyset. This would be a little too much for this article so we won't cover it here.


Changing The Default Configuration via MYCNF.E

EPM's standard configuration is stored in a file calles STDCNF.E. Every definition primitive is given a default value here. You should not change this file since it may be changed with the next release of EPM and you had to rewrite all your changes. Instead you should write a file called MYCNF.E which is included before STDCNF.E andso settings you specify here override settings in STDCNF.E.

Configuration Constants

Configuration constants are constants so you can set them using the const statement:

const
        FOO = 'VALUE'

There are, well, quite a lot of configuration constants within EPM so we will cover only a subset which I think are the more important ones. See the EPM User's Manual for the complete set of constants. Along with the constants the default values are given:

ALTERNATE_KEYSET=1
Defines if support for alternate keysets is included. The default is to include it. Support for alternate keysets allows you to define user keysets and switch between them. It is needed for C, E, Pascal, or REXX syntax assist. If it is set to 0 these are not included. Also MYKEYSET.E would not be included.
AUTOSAVE_PATH=
Specifies the path where "autosave" files will be placed. The default value means that they're placed in the current directory. There is also an AUTOSAVE PATH setting in EPM's settings notebook. The path specified there overrides the setting in MYCNF.E
BACKUP_PATH=
Specifies the path setting for backup files. Same as for AUTOSAVE_PATH but there is no setting in the notebook for this one and it has another option: '=' will place the backup file in the same directory as the saved one (and give it the extension '.BAK'). The backup directory must end with a backslash.
COMPILER_ERROR_COLOR=RED+WHITEB
When used within the Workframe/2, EPM displays compiler errors. This constant is used to set the color used for the errors. Default is red on white. See <a HREF="#configcol">Configuring Colors</a>
C_SYNTAX_ASSIST=1
Set this to 1 to include syntax assist for the C language. Syntax assist automatically expands specific keywords into the corresponding language constructions.
C_TABS=3
Specifies the default tab size for C files.
DEFAULT_PASTE=
Use this setting to define the default behaviour of the paste key (Shift+Insert). always pastes as new lines, 'B' pastes as a block and 'C' pastes as a stream of characters.
DRAG_ALWAYS_MARKS=0
In advanced marking mode on dragging the mouse a new block is only marked if there is no one currently marked. This can be helpful, e.g. if you want to set the cursor using the mouse and don't want the current mark to be deselected. It can be quite annoying if you're not used to it so you can set this switch to 1 to turn it off. DRAG_ALWAYS_MARKS has no effect in CUA-marking mode.
ENHANCED_ENTER_KEYS=0
Set this one to 1 to be able to set the action performed by the Enter keys with EPMs settings notebook. Using the default value only lets you use configuration constants (ENTER_ACTION and C_ENTER_ACTION, see EPM Users Guide).
ENHANCED_PRINT_SUPPORT=0
Set this to 1 to tell EPM to bring up the "Print" dialog when you specify the print command from the menu instead of just printing the file.
EPATH='EPMPATH'
Specifies the environment variable used to store EPM's search path.
EXTRA_EX=0
This must be set to 1. Code size for .EX-files is limited to 64K, which is too small for the standard configuration. If EXTRA_EX is set to one it is split into two files, EPM.EX and EXTRA.EX both of which are loaded on startup.
E_SYNTAX_ASSIST=1
Enables syntax assist for the E language. See <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.
E_TABS=3
Sets the default tab setting for .E files. See <a HREF="#ctabs">C_TABS</a>.
HELPFILENAME='epmhelp.qhl'
Sets the filename for the "Quick Help" file.
HIGHLIGHT_COLOR=
Sets the color that is used to draw these fancy circles around found search strings. There is no default so you have to specify it. See <a HREF="#configcol">Configuring Colors</a>
INCLUDE_WORKFRAME_SUPPORT=1
Specifies if support for IBM WorkFrame/2 is included in the configuration.
MARKCOLOR=Blue+GreyB
Sets the color used to mark marked marks in your file. See <a HREF="#configcol">Configuring Colors</a>
MENU_LIMIT=0
You can edit several files in one EPM window using the file ring. Usually these files can be accessed with the Ring menu command which brings up a dialog box containing the files that are currently being edited. Specifying any number greater than 0 (n) for this constant tells EPM to add n files to the Ring menu and bring up the dialog box only if there are more than n files in the ring. There is no limit for n but 120 makes no sense.
MESSAGECOLOR=Light_Red+WhiteB
Sets the color used to display the message line or error messages. See <a HREF="#configcol">Configuring Colors</a>
MY_DEFAULT_EDIT_OPTIONS=
Set default options for the edit command. These default options will be overridden by options specified on each specific edit command.
MY_DEFAULT_SAVE_OPTIONS=
Same as MY_DEFAULT_EDIT_OPTIONS for the save command.
MY_DEFAULT_SEARCH_OPTIONS=
Another one, this time for search commands!
MY_SAVE_WITH_TABS=0
Set this to 1 to tell EPM to automatically compresses spaces to tabs when saving. This is the same as specifying '/t' for MY_DEFAULT_SAVE_OPTIONS.
NLS_LANGUAGE='english'
Sets the language for National Language Support.
P_SYNTAX_ASSIST=1
Includes Pascal syntax assist. See <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.
P_TABS=3
Sets the tab size for Pascal files. See <a HREF="#ctabs">C_TABS</a>.
REXX_SYNTAX_ASSIST=1
Includes REXX syntax assist. See <a HREF="#csyntaxassist">C_SYNTAX_ASSIST</a>.
REXX_TABS=3
Sets the tab size for REXX files. See <a HREF="#ctabs">C_TABS</a>.
SETSTAY=0
This option controls where the cursor is located after a change command. 0 means it is located on the last changed string, 1 means it stays where it was before the command and '?' defines a STAY command to change this behavior.
STATUS_TEMPLATE='Line %l of %s Column %c %i %m %f'
This is the status string used to configure the status line. The template can be up to 128 characters long and may contain characters and status tags. A status tag make EPM display certain status information. The following tags are defined:
<small>
    %A   Number of changes made since last autosave.
    %C   Current column number
    %F   Number of files in ring
    %I   Insert or replace state
    %L   Current line number
    %M   Modified status
    %S   Total number of lines in current file
    %X   Hexadecimal value of current character
    %Z   ASCII value of current character
    </small>
SUPPORT_TECHREF=0
Set this to 1 to add a 'View Technical Reference' command to the help menu.
SUPPORT_USERS_GUIDE=0
Set this to 1 to add a 'View Users Guide' command to the help menu.
SUPPORT_USER_EXITS=0
User Exits are procedures that are called by certain command, e.g. load and save. Setting SUPPORT_USER_EXITS to 1 enables this feature. See <a HREF="#yourowncomandproc">Your own commands and procedures via MYSTUFF.E</a>
SYNTAX_INDENT='3'
Specifies the number of spaces used for syntax indent when syntax assist is used.
TEXTCOLOR=Black+WhiteB
Specifies the color used to display normal unmarked text in the edit window. See <a HREF="#configcol">Configuring Colors</a>
TOGGLE_ESCAPE=0
Set this to 1 to define the ESCAPEKEY command.
TOGGLE_TAB=0
Set this to 1 to define the TABKEY command.
TRASH_TEMP_FILES=0
If set to 1 temporary files (which begin with a '.') will be quit without warning even if not saved. This may be useful (e.g. if you use the ALL command and don't want to be asked if you wanted to save the '.ALL' file upon exit).
UNDERLINE_CURSOR=0
Specifies the style of the cursor used in the editor. Default is a vertical bar in front of the actual character. Set to 1 changes it to a horizontal bar below the actual character.
UNMARK_AFTER_MOVE=0
Use this switch if you want marked text to be unmarked after a move operation. Default is that it is not.
USE_APPEND=0
Set this to 1 to make EPM search for files along DPATH if they can't be found in the current directory.
WANT_ALL=0
Set this to 1 to include the ALL command.
WANT_BOOKMARKS='LINK'
Specifies whether or not bookmark support is included. The default is that bookmark support is linked at runtime (or included in EXTRA.EX if this is used).
WANT_CHAR_OPS=1
Set this to 0 to disable character marking mode support.
WANT_CUA_MARKING=0
Set this to 1 to use the CUA marking style instead of the EPM block marking. A value of SWITCH adds a switch for this to the Preferences menu.
WANT_DRAW='F6'
Includes the DRAW command. Default is to include it and define the 'F6' key for it. Other options are 1 and 0.
WANT_DYNAMIC_PROMPTS=1
Includes dynamic prompt support. If it is included (default) there is a Prompting option in the Frame Controls menu. Prompting shows a description of the currently selected menu item in the message line.
WANT_ET_COMMAND=1
Includes the ET command to issue ETPM from EPM.
WANT_KEYBOARD_HELP=0
If keyboard help is activated the CTRL-H key is redefined to issue a keyword help procedure that looks through the files specified in the HELPNDX environment variable for the keyword under the cursor. If it is found help for this keyword is given as specified in the .NDX-file, usually by invoking VIEW.EXE.
WANT_LONGNAMES=0
Includes support for long names. A value of SWITCH defines a Longnames command.
WANT_PROFILE=0
Includes support for a REXX profile. If profile support is included EPM looks for a file called PROFILE.ERX upon startup and executes it if found. A value of SWITCH defines the Profile command.
WANT_STACK_CMDS=0
Includes a set of stack commands. The commands are PushPos, PopPos, SwapPos, PushMark, PopMark, SwapMark and can be used to create a stack to store cursor positions and marks. A value of SWITCH defines an entry in the Preferencs menu.
WANT_STREAM_MODE=0
Set this to 1 to make EPM use a stream mode approach to file editing that is the edited file is seen as a continuing stream of characters. In the default mode a file is interpreted as a set of lines. A value of SWITCH enables you to switch between these modes at runtime using the Preferences menu.

See Example MYCNF.E

Configuring Colors

EPM includes the file COLORS.E which defines a set of color values to be used within EPM macros. The available constants are:

Foreground ColorsBackground Colors
BLACK0 BLACKB0
BLUE1 BLUEB16
GREEN2 GREENB32
CYAN3 CYANB48
RED4 REDB64
MAGENTA5 MAGENTAB80
BROWN6 BROWNB96
LIGHT_GRAY7 LIGHT_GRAYB112
DARK_GREY8 DARK_GREYB128
LIGHT_BLUE9 LIGHT_BLUEB144
LIGHT_GREEN10 LIGHT_GREENB160
LIGHT_CYAN11 LIGHT_CYANB176
LIGHT_RED12 LIGHT_REDB192
LIGHT_MAGENTA13LIGHT_MAGENTAB208
YELLOW14 YELLOWB224
WHITE15 WHITEB240

These constants may be used to set the display color variables. Note that these constants may only be used if COLORS.E was included. This may not be the case for external commands that include MYCNF.E. Use the COMPILE IF statement to include them if the color constants are defined. Also note that the color variables are not constants and therefore should be define'd.

compile if defined(BLACK)
  define
     TEXTCOLOR       = BLACK + WHITEB
     MARKCOLOR       = BLUE + GREYB
     STATUSCOLOR     = BLACK + WHITEB
     MESSAGECOLOR    = LIGHT_RED + WHITEB
     DRAGCOLOR       = YELLOW + MAGENTAB
     HIGHLIGHT_COLOR =
compile endif

Example MYCNF.E

Here's an example MYCNF.E file.


const
   NLS_LANGUAGE = 'ENGLISH'
   AUTOSAVE_PATH = '\OS2\EPM\AUTO\'
   BACKUP_PATH = '\OS2\EPM\BACK\'
   TEMP_PATH = '\OS2\EPM\TEMP\'
   EPATH = 'EPMPATH'
   C_TABS = '4'
   E_TABS = '4'
   REXX_TABS = '4'
   P_TABS = '4'
   SYNTAX_INDENT = '4'
   USE_APPEND = 1
   SETSTAY = '?'
   TRASH_TEMP_FILES = 1
   WANT_ALL = 1
   WANT_RETRIEVE = 1
   WANT_KEYWORD_HELP = 1
   WANT_LONGNAMES = 'SWITCH'
   WANT_STACK_CMDS = 'SWITCH'
   WANT_CUA_MARKING = 'SWITCH'
   WANT_STREAM_MODE = 'SWITCH'
   WANT_DYNAMIC_PROMPTS = 1
   WANT_PROFILE = 'SWITCH'
   MY_DEFAULT_EDIT_OPTIONS = '/t'
   SUPPORT_TECHREF = 1
   SUPPORT_USERS_GUIDE = 1
   SUPPORT_USER_EXITS = 1
   EXTRA_EX = 1
   DEFAULT_PASTE = 
   TOGGLE_ESCAPE = 1
   TOGGLE_TAB = 1
   DRAG_ALWAYS_MARKS = 1
   MENU_LIMIT = 25
   SMARTFILE = 1

compile if defined(BLACK)
define
   HIGHLIGHT_COLOR = GREEN + GREENB
   DRAGCOLOR = LIGHT_GREY + DARK_GREYB
compile endif

Adding your own key definitions via MYKEYS.E

The file MYKEYS.E should be used for your own key definitions and redefinitions. It is included into E.E after most of the definition stuff and directly before MYSTUFF.E. Currently it does not matter which of those you use to store your key DEFs but that may change.

Key definitions start with a DEF statement and give the key name with an additional S_ for Shift+key, A_ for Alt+key or C_ for Ctrl+key in front of it. Alphanumeric keys are addressed by their alphanumeric value while special keys are listed below:

F1-F12The function keys
DELThe delete key
INSThe insert key
UP, DOWN, LEFT, RIGHTThe cursor keys
PGUP, PGDNThe paging keys
HOME, ENDHome and End :)
ENTER, ESC, TABThe respective keys.
PADENTERThe pad-enter key on AT or MFII keyboards.
PAD5(S_ only) The pad-number 5 on AT or MFII keyboards
EQUAL(A_ only) =
LEFTBRACKET, RIGHTBRACKET(A_ and C_ only) (,)
MINUS(A_ and C_ only) -
BACKSPACEBackspace
BACKSLASH(C_ only) \
PRTSC(C_ only) Print Screen

Following the DEF statement you simply start writing your key function.

def a_s=
   'saveall'

This makes ALT+S execute the SAVEALL command.

You may, of course, also include other key definition files in MYKEYS.E, e.g. REVERSE.E and GLOBFIND.E from the EPM distribution demos:

include 'reverse.e'
include 'globfind.e'

Example MYKEYS.E

The following example MYKEYS.E defines an undo key for ALT+U. It uses EPM's undoaction command to take back changes one by one. So you don't have to use the UNDO-dialog if you just want to take back a few changes. The one thing making this a little bit complicated is the fact that the undo itself is regarded as a change and therefore is stored by undoaction. So if you did undo twice you would restore the state before the undo. However the intention of the undo key is to be able to take back more than one step. The solution is to store information about which steps in the undo-chain are UNDOs itself and to skip them.


/* This is an example MYKEYS.E file defining an undo key
   <C> 1993 Joerg Schwieder, Berlin, Germany               */
-- define ALT-U
def a_u=
-- define an universal variable to store UNDOs taken
    universal undostates
-- get the first and the last actions stored in the UNDO-tree
    undoaction 6, states
-- parse the 2 values into sfirst and slast
    parse value states with sfirst slast
-- copy our undo-states
    undoakt = undostates
-- save the actual state to our new UNDO-state list
    newstate = slast
-- last entry we could UNDO to
    slast = slast - 1
-- loop through the UNDO-tree
    while slast >= sfirst do
-- look at our last undo
        parse value undoakt with thisone undoakt

        if (thisone < slast) or
           (not thisone) or
           (thisone < sfirst) then

            -- if its older than the last tree entry or if
            -- we never undid - leave, it's OK!
            leave

        endif

-- add our last UNDO to our new list
        if thisone then newstate = newstate' 'thisone; endif
-- if the actual tree entry is an old UNDO
        if thisone = slast then slast = slast - 1; endif
-- look at the one before
    endwhile
-- if a possible tree-entry was found,
    if slast >= sfirst then
-- add it to the start of the new UNDO-list
        newstate = newstate' 'slast

    endif
-- add the remaining old UNDO list to the new one
    while undoakt and (thisone >= sfirst) do
-- but strip entries no longer in the UNDO tree
        newstate = newstate' 'thisone

        parse value undoakt with thisone undoakt

    endwhile
-- set undostates to the new list
    undostates = newstate
-- if an entry was fond
    if slast >= sfirst then
-- UNDO
        undoaction 7, slast

    else
-- else remove the actual entry from the list
        parse value undostates with . undostates

    endif

/* This is the sample ALT-S definition for SAVEALL */

def a_s=
    'saveall'

/* Include REVERSE and GLOBFIND keys from the
EPM distribution demos if present. */

tryinclude 'reverse.e'
tryinclude 'globfind.e'

Select this to go to the next section

Your own commands and procedures via MYSTUFF.E

This is the place to put your own commands and procedures. Usually you won't put them into the file directly but include other files. Don't be concerned if these files contain key definitions as well. EPM includes MYSTUFF.E directly after MYKEYS.E. The distinction is for organizational purposes. You might want to put everything in MYSTUFF.E, especially if you write large extensions part of which are key definitions and if you don't want to split them up into several files.

include 'saveall.e'

This would put the SAVEALL command into the default configuration.

Commands are defined using the DEFC statement followed by the command's name, arguments are passed through arg(1) which returns a parameter string:

defc gocol
    .col = arg(1)

This defines a GOCOL command that moves the cursor to the column passed as parameter.

Example MYSTUFF.E

The following sample MYSTUFF.E file uses another EPM feature - user exits. Several hooks are spread in the editor code which give user procedures notice of certain events, e.g. a file is being saved. User exits are procedures that are called by EPM if they are defined. We will use them to write an autostart feature that "reminds" of its closedown state. If EPM is closed with open files, these filenames are stored in EPM.INI; should EPM be started later without parameters, it will reload these files. Additionally the cursor position in each open file is stored in extended attributes upon shutdown; reloading this file later repositions the cursor right where it was.


This feature is quite useful when you are editing several large files. If you want to leave EPM but continue the next day just close down EPM and if you restart it the next day without parameters; you are right back where you were without having to load all your files and having to find your way through your code back to where you left.

There is just one drawback: Since defmain_exit has to be called from MAIN.E it has to be included before it and therefore has to be included into MYCNF.E. We include this section as a file called MAINEXIT.E into MYCNF.E.

MYSTUFF.E:

include 'saveall.e'

defc gocol
    .col = arg(1)

/* For the autoload feature we maintain a list of
the currently open files in a profile entry named
STARTUP_FILES. The first one is the file actually
edited to make sure it comes up on restart */

/* This one makes sure that the file that was on
top on shutdown will reappear there on startup.
Defselects are called whenever a file is selected */

defselect

   /* The application name and INI-handle
   are stored in these global variables */

   universal appname, app_hini

   -- Save cursor position
   psave_pos(spos)

   -- get actual filelist
   filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')

   -- find actual file
   if wordpos(.filename, filelist) then

      -- and remove it
      filelist = delword(filelist,
                         wordpos(.filename,filelist),1)

   endif

   if (not wordpos(.filename, filelist)) and
      (substr(.filename, lastpos('\', .filename)
      + 1, 1) <> '.') then

       -- add the actual filename at the beginning
       filelist = .filename' 'filelist

   endif

   -- write the new list to the INI-file
   setprofile( $HINI_PARM appname, 'STARTUP_FILES',
               filelist )

   -- Restore cursor position
   prestore_pos(spos)

-- called just after file was saved
defproc postsave_exit (fname)

   /* oldfile is the old filename
   if file was renamed */

   universal appname, app_hini, oldfile

   -- Save cursor position
   psave_pos(spos)

   -- get the old file list
   filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')

   -- if old filename is in the list
   if wordpos(oldfile, filelist) then

       -- delete it
       filelist = delword(filelist,
                          wordpos(oldfile,filelist),1)

   endif

   if (not wordpos(fname, filelist)) and
      (substr(fname, lastpos('\', fname)
      + 1,1) <> '.') then

       -- Add actual filename if its not
       -- a tempfile ('.---')
       filelist = fname' 'filelist

       -- remove the 'and (substr...' section if
       -- you want to restart temp files

   endif

   -- store the new list
   setprofile( $HINI_PARM appname,
               'STARTUP_FILES', filelist )

   -- Restore cursor position
   prestore_pos(spos)

 -- called if file was renamed
 defproc rename_exit (oldfile, fname)

   universal appname, app_hini

   -- Save cursor position
   psave_pos(spos)

   -- same as for postsave_exit
   filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')

   if wordpos(oldfile, filelist) then
      filelist = delword(filelist,
                         wordpos(oldfile,filelist),1)

   endif

   if (not wordpos(fname, filelist)) and
      (substr(fname, lastpos('\', fname)
      + 1, 1) <> '.') then

       filelist = fname' 'filelist

   endif

   setprofile( $HINI_PARM appname,
               'STARTUP_FILES', filelist )

   -- Restore cursor position
   prestore_pos(spos)

-- called if file is closed
defproc quit_exit (fname)

   universal appname, app_hini

   -- just delete entry
   filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')

   if wordpos(fname, filelist) then
      filelist = delword(filelist,
                         wordpos(fname,filelist),1)

   endif

   setprofile( $HINI_PARM appname,
               'STARTUP_FILES', filelist )

-- Defload functions are called whenever a file was loaded

defload        /* same as for namefile and savefile,
               just that there are no old names to
               delete */

   universal appname, app_hini
   filelist = queryprofile( $HINI_PARM appname,
                            'STARTUP_FILES')

   if (not wordpos(.filename, filelist)) and
      (substr(.filename, lastpos('\', .filename)
      + 1, 1) <> '.') then

       filelist = .filename' 'filelist

   endif

   setprofile( $HINI_PARM appname,
               'STARTUP_FILES', filelist )

/* Here comes the Cursor position feature */

-- issued just before a file is saved
defproc presave_exit

   -- used to store the filename for postsave_exit
   universal oldfile

   -- delete old 'EPM.POS' entry in the EAs
   delete_ea('EPM.POS')

   -- get cursor and screen position,...
   psave_pos(screenpos)

   -- and store it in the EA
   'addea EPM.POS' screenpos

   -- this one's needed for the restart feature
   oldfile = .filename

-- This one's for setting the Cursor and window
--position for the loaded file
defload

    if find_ea('EPM.POS', ea_seg, ea_ofs, ea_ptr1,
       ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then

        -- if there's an EPM.POS EA...

        -- that's the actual file
        getfileid myid

        'postme restore_ORG_pos
        'myid get_EAT_ASCII_value('EPM.POS')

         /* restore postions. have to post it 'cause
         the screen may not yet be painted. Also I
         had to make this the last of my defloads to
         make it work correctly */

    endif

-- This sets the cursor and screen-positions.
-- It does the same as
defc restore_ORG_pos

        -- prestore_pos except for being passed
        -- the fileid as first parameter

        parse value arg(1) with myid fline fcol cx cy
        myid.cursorx = cx
        myid.cursory = cy
        myid.line = fline
        myid.col = fcol

MAINEXIT.E:


define
-- 5.20 adds a HINI to the *Profile calls.
compile if EVERSION >= '5.20'
   HINI_PARM = 'app_hini,'
compile else
   HINI_PARM = ' '
compile endif

-- called just before files are loaded upon startup
defproc defmain_exit (var cmdline)

   universal appname, app_hini

   -- this is the command line + 'e '.
   -- If no parameters are specified ...
   if cmdline = 'e ' then

       -- ...add the ones from 'STARTUP_FILES'
       cmdline ='e 'queryprofile( $HINI_PARM appname,
                                  'STARTUP_FILES' )
   endif

Editor startup code via MYMAIN.E

MYMAIN.E is included and executed directly after the editors own startup code so you can put code here that has to be executed once after the editor was initialized e.g. recognizing messages for other applications (sorry, could not think of anything else). With the exception of the different include position handling of MYMAIN.E is the same as for MYSTUFF.E

File initializations and focus changes via MYSELECT.E

MYSELECT.E is another file that does not differ much from MYSTUFF.E. It is included after MYMAIN.E but before MYSTUFF.E. Theoretically, it should contain DEFSELECTs, code that is executed whenever a file is selected, but this does not necessarily have to be the case so we put this code into MYSTUFF.E also. See the MYSTUFF.E example.

Typical tasks for DEFSELECTs are cursor positioning, file-type specific changes to the keyset or the messageline or adding of file-type specific menus etc. Using DEFSELECTs you can change the behavior of the editor depending on the file-type.

Summary

We have seen how the EPM toolkit can be used to change your EPM configuration and how commands that you write can be integrated into the system. A little thought can yield a good editor for your uses at a great price. Also, support for EPM-related topics can already be found in comp.os.os2.programmer.misc and is provided by Larry "Mr. Macro" Margolis, who wrote most of the standard macros provided by EPM and is currently a member of the EPM development group within IBM.