Notes about this presentation
Executing modified Rexx code without you having to SAVE it
Coding assistance for Classic Rexx and HTML
Split screen. Both horizontal and vertical
Finding the differences between two files
File selection assistance at edit time
Selecting a file from the ring of active files being edited
Switching between a limited subset of all the files in the ring
Carrying skeleton code within a macro, instead of in a separate file
Packaging code to include a Table of Contents and origin, using 7zip
Extended Help for THE, built from the C source code. Includes a User Exit to integrate your own macros.
I've attempted to document the main points I want to demonstrate, both in prose and screen shots. Of course I can't guarantee a one-for-one correlation. There may be either more or less here!
This is not an "Introduction to THE". Some of THE's basic features were presented last year and will not be repeated.
Unlike Xedit, in THE the buffer for holding commands is shared with all the files in the ring. This can be a great help when making the same change, or doing the same search, to multiple files.
Since I prefer the Xedit style, I added an option flag in the smart_enter code to implement command recall as separate macros: cmdsave and retrieve.
This allowed two other enhancements:
The Menu option comes in two flavors:
|?MN||Displays a popup of saved commands to select from|
|?M||Displays the popup and sets the internal pointer to the item selected|
Now command recall not only behaves like Xedit, but also has the menu behavior similar to that of X2.
Here is a trivial example I created in my usual playpen file so I could demonstrate the popup:
You select the command you want by using the arrow keys and then press ENTER. The command is put in the cmdline for further editing or execution, just as though you had typed it yourself.
Currently, the number of commands saved is 10.
rexxoutput filehaving been issued by the profile.
For example, here I've navigated to the ooRexx/Samples and edited qtime.rexto add my name to the message:
After I execute the run macro, THE captures the output and shows us:
It will try to ensure that the PATH is correctly set, but some BSF4OORexx code can confuse it.
If we had added a TRACE R statement, we might see something like:
captured by THE.
If we had been doing intensive debugging, at some point we might have inserted this to execute dumpvars.rex
Interpret dumpvars(,'edit') Interpret edit
to see what the variables were set to:
The file created by dumpvars remains behind for later perusal and ultimately should be deleted, either manually or using dumpvars itself.
When we're finished, we simply QQUIT from both files.
define enter macro smart_enter
The code generated is quite dense. That's because of my poor
vision and the limited size of the screen (26x80), as shown
at the bottom of the screen.
Here's an example:
Notice that Do is on the same line to save vertical screen space and to allow the
statements to undent evenly without any gaps. This provides visual confirmation that all the matching
statements are present.
Since this is a subroutine, the macro rexxfmt.the automatically indents it two characters.
smart_enter behaves much like you would expect it to, but it does not keep a history of what you've done and try to anticipate what you want next. What it does next is based on the line where the cursor is when the ENTER key is pressed.
Here's a summary:
How it handles a
is, perhaps, somewhat different from what you might ordinarily expect. Here are three examples to help clarify how it behaves:
The intent, in all cases, is to reduce the chance for keying errors and to make writing the code as easy as possible.
Currently, HTML is limited to the markup used most often, as this snippet of the actual code shows:
markupand all that is required is to enter the character string by itself in a blank line, or to position the cursor on the line with the
"</whatever>"end markup to get another set of that markup.
<br />gets special handling, since it is often repeated on the same line. As long as the sequence br appears to be a word, it will be expanded to the correct markup.
<!-- Use VIEW to follow this link for help with html tables: http://www.w3schools.com/tags/tag_table.asp --> <table width="90%" align="center"> <tr> <th> </th> <th> </th> </tr> <tr> <td> </td> <td> </td> </tr> </table>
<dl> <dt> ? </dt> <dd> ? </dd> </dl>
<ul> <li> </li> </ul>
Although the above examples show the markup starting at the leftmost column, it will be put wherever the triggering string is found.
The screen 2 command will split the screen into two views. By default, the arrangement is Horizontal, but Vertical can be passed if needed.
If there are multiple files in the ring, the second (bottom/right) view will be the next file in the ring.
When there is only one file, you get two views of it that can be managed individually. You might, for instance, explore the main line code in the top view and each subroutine (perhaps usingToSub and RetSub) in the bottom view.
One interesting side-effect of having two views of the same file: when the all command is used in one view, the other view will show the lines that were not selected.
Horizontal split of a file. The all /if/ and more /end/ commands have been used, as can be seen in the top view. The bottom view shows the other lines.
Horizontal split showing two files: The source for this document and the directory for it. Notice that the top view does not show the reserved function key lines.
Vertical split of the same two files. Notice the reserved function key lines.
Even though THE only handles two views, you can do some interesting things. Here my trycolors macro is showing a list of colors and elements to select on the left side. The right side will be used to show the result.
My enhanced version requires a split screen and allows two views of a single file. This would allow you to compare two subroutines in the same file.
The macros both and other can be handy for resynchronizing the files to a common point before running diff again.
Below I've used both to skip over the first change I made to diff and then found the second change.
Diff of two versions of diff
To make things easier, I wrote the newfile macro, which does two things when THE thinks a file is new:
For example, a subset of my favorites looks like this:
C:\MyTHEstuff C:\MyTHEstuff\Symposia\Symposium_2012 C:\MyTHEstuff\Symposia\Symposium_2011 C:\MyRexxStuff C:\MyTHEstuff\Email C:\RexxLA2011
Instead of using the dirs macro to first navigate to the folder and make my selection from there, I could just enter:
which is in the
C:\RexxLA2011folder and it would automatically be found.
When an exact match isn't found, newfile does a wildcard search, sorts the result by descending date and presents a popup to select from:
newfile: Wildcard search result when x log was entered
The ringlist macro displays a popup of all the files in the ring for you to select from, navigating with the up/down arrow keys. The format is controlled by an EDITV setting of your choice in your profile:
"EDITV SETL RINGLISTORDER NAME_FIRST" "EDITV SETL RINGLISTORDER NAME" "EDITV SETL RINGLISTORDER FILEID" "EDITV SETL RINGLISTORDER NONE"This is a reworked version of the original Kedit code, making it compatible with THE and adding:
ringlist with abbreviation
Originally written to flip-flop between two files (thus its name), it wasn't long before I realized it should be able to do more, so now the limit is four files.
while editing a file you want it to remember, just enter
in the cmdline.
After you've done this for the files of interest, use the FF function key to flip between them.When you enter ff ? you see:
It is often a lot easier to just imbed the skeleton in the macro that needs it. A simple example is within smart_enter:
TABLE_HTML: first=thisline()+2 /* <!-- Use VIEW to follow this link for help with html tables: http://www.w3schools.com/tags/tag_table.asp --> <table width="90%" align="center"> <tr> <th> </th> <th> </th> </tr> <tr> <td> </td> <td> </td> </tr> </table> */ last=thisline()-2 'replace' sourceline(first) 'extract /line/curline/' do s=first+1 to last 'input' sourceline(s) end ':'line.1 'cursor file' line.1+6 6 'sos makecurr' call prompt , 'Position cursor to the "</" line and press ENTER for another pair' return
The results of this technique were shown earlier.
The same technique can be used to initialize Rexx/THE code, thus ensuring consistency of a set of labels, variables and subroutines that are commonly needed.
The macro newfile, which you saw earlier, does this for Rexx and THE code, initializing the header block (which is used for Help) and including subroutines to handle parsing keyword arguments, instead of obscure, meaningless 'switches' based on the limited capability of early pc chips and memory limitations.
Combining this with the getvar function I presented back in December at the Rexx Symposium in Aruba, yields the following THE code:
INIT_REXX: copyright_name=getvar('copyright_name') author=getvar('author') hdr=fname.1()'.'ftype.1()': See "Purpose", below' cpyr='Copyright (C)' Word(Date(),3) copyright_name notic='This is free software. See "Notice:" at the bottom of this file' sc='/'||'*' ec='*'||'/' 'input' sc ec 'beghelp=thisline()+1' sc 'input' hdr 'input' cpyr 'input' notic 'input ' 'input Author:' author 'input Date:' Date() Time() 'input ' 'input Purpose:' 'input ' 'input Syntax:' 'input' ec 'input endhelp=thisline()-2' Call skeleton '-/Purpose:' 'extract /curline/' 'cursor escreen' curline.2 Length(curline.3)+2 'set alt 0 0' exists?=1 Call next 'msg','New file boilerplate inserted. Fill in "Purpose:"', 'and code away!' Return
SKELETON: is where all the subroutines are extracted from the macro and added to the new file, using the same technique as TABLE_HTML: above.
The initial result might look like this:
INIT_VARS: valids='? /? -? Help /Help -Help --Help' /* Keywords */ abbrev='1 2 2 1 2 2 3 ' /* Minimum abbreviation */ flags=copies('Help? ',words(valids)) /* Flag to set for keyword */ helps=valids valids=valids ' ' --< Your keywords abbrev=abbrev ' ' --< Your abbreviations flags=flags ' ' --< Your flagnames flags=flags 'Unknown? Keyword_parms?' /* Always the last ones */A little later in the code is where you define keywords that have parameters.
About 278 lines of commentary and code have been provided to get you started.
You saw earlier the Help for the ff macro, but I didn't show the interesting part of the source:
Purpose: Flip-flop between a selection of up to &maxsaves files in the ring. Syntax: &sme [Clear | Add | List | Delete] : &sme [&helps] : &sme If you haven't SET MACRO ON then use the command: macro &sme Notes: &sme manages a subset of the files in the ring to allow you to easily rotate through the list it maintains. It's of particular use when you have a lot of files in the ring but you want to concentrate on just a few of them without using something like RINGLIST all the time. Or even NEXTWINDOW, PREVWINDOW. Instead, just enter: &sme or put MACRO &sme on a hotkey/pfkey and use &sme ADD while editing a file you want &sme to keep.The HELP subroutine will resolve all the ampersand variables. So if the macro gets renamed, the only change necessary is the fileid near the top of the header. Also notice that the number of fileids that can be saved is set by the variable maxsaves. If the variable is changed, the Help will still be correct!
Another tool, FCOPY, could compress files into a single PACKLIB file, much like any zipping tool does on the pc.
Of course there were several tools for handling lists of files.
One of the goals I had was to make it easier for THE users to freely exchange tools amongst themselves, limiting the need to put them in separate folders and having to update the MACRO_PATH setting to include another folder.
An outgrowth of this idea was what I now call "Virtual Directories", which I presented in Part One in Aruba.
Briefly, a Virtual Directory is a list of fully qualified fileids and macros that recognize it and treat it just like it was a DIR.DIR that THE shows when you issue the dir command. For my purposes, I've chosen a file extension (file type, as it's known in THE) of PKG, upper cased, as shown, so that it stands out. See last year's presentation for more details.
Creating a package is as simple as:
The next thing to do is to run the
macro to resolve everything. At completion, it will show you the TOC file that it created:
The LOL looks like this:
helpx_LOLIt contains a LST entry for each unique path, since 7zip uses relative paths when it builds an archive.
The LST files themselves contain the fully qualified fileids of the files to put in the archive.
There is also a pointer back to the parent TOC file.
Here is the LOP:
helpx_LOPwhich provides documentation about what PKG files are present.
You might have noticed that there is a PKG that did not appear in the original PKG file:
C:\MyTHEstuff\LesK_Package_Notes_PLEASE_READ.txt.PKGIt contains information about the packaging technique and how to take full advantage of it, including the macros to do so. One of the macros, fix_pkg, can be tailored to fix the contents of the PKG, TOC, LOL, LOP and LST files to match where you unzipped the package to. If a line in such a file matches its own fileid, and some do, that line is skipped. This leaves behind a pointer to where the file originally lived.
Another macro, addtoring, can be used to add files from a list to the ring of files being edited.
That completes gathering and resolving all the information associated with a PKG.
The next step is to build the zip file(s) with the package macro.
If the package is to be sent to another THE user, then simply enter:
while still in the TOC file.
If it is going to someone who doesn't need all the additional THE information, then enter:
package will build the zip files and put them in the originating folders.
It will also build a file like this, for the example we've been using:
This makes it easier to send the zip files to someone else, perhaps with the att macro, which recognizes the .zips file type and attaches the files to the note when the note is sent.
All of them are helpful and each has its own advantages, but none can readily be extended to encompass user macros or other environments. Plus, they just don't work like the flexible CMS and Xedit Help that I'm used to.
The source code for THE is kept in individual files, which I created a PKG file for:
C:\MyTHEstuff\THE_Source\LesK_Helpx_Source_Files.PKG C:\MyTHEstuff\THE_Source\comm1.c C:\MyTHEstuff\THE_Source\comm2.c C:\MyTHEstuff\THE_Source\comm3.c C:\MyTHEstuff\THE_Source\comm4.c C:\MyTHEstuff\THE_Source\comm5.c C:\MyTHEstuff\THE_Source\commset1.c C:\MyTHEstuff\THE_Source\commset2.c C:\MyTHEstuff\THE_Source\commsos.c C:\MyTHEstuff\THE_Source\query.c C:\MyTHEstuff\THE_Source\appendix.1 C:\MyTHEstuff\THE_Source\appendix.2 C:\MyTHEstuff\THE_Source\appendix.3 C:\MyTHEstuff\THE_Source\appendix.4 C:\MyTHEstuff\THE_Source\appendix.7 C:\MyTHEstuff\THE_Source\overview C:\MyTHEstuff\THE_Source\glossary
For my purposes, the ones I needed were grouped into:
/*man-start********************************** **man-end************************************/and writing the data to
The .txt files are preformatted to be used as "List" files, with one line for each command, like this:
add - add blank line alert - display a user configurable dialog box with notification all - select and display restricted set of lines backward - scroll backwards [n] screens bottom - move to the bottom of the file cancel - quit from all unaltered files in the ring cappend - append text after column pointer
The .idx files are used as index files to the actual help prose. For example:
C:\MyTHEstuff\THE_Source\comm1.c (GET - :47 3 ) C:\MyTHEstuff\THE_Source\comm1.c (GET add - :53 30 ) C:\MyTHEstuff\THE_Source\comm1.c (GET alert - :133 28 ) C:\MyTHEstuff\THE_Source\comm1.c (GET all - :185 36 ) C:\MyTHEstuff\THE_Source\comm1.c (GET backward - :370 29 ) C:\MyTHEstuff\THE_Source\comm1.c (GET bottom - :482 19 ) C:\MyTHEstuff\THE_Source\comm1.c (GET cancel - :550 20 )
These files are the basis for the Extended Help Facility. The same methodologies can be applied to provide additional information, all integrated into the help command provided by THE, using the
synonym help macro helpxcommand.
This tells THE to run the helpx macro when you enter the help command.
The syntax looks like this:
Its default Menu mode with no arguments yields:
If you pass an argument, for instance:
As you navigate the menu, your selection is shown in red. The colors, and many other settings are, of course, configurable by editing helpx_config.rex to suit your own tastes.
The list argument, like this:
help commands listoverrides the default Menu mode to give you:
After you press Enter you have a regular file that you can search, selecting a command by putting "\" in the prefix area.
You can leave this file in the ring and always return to it using F2, ff or ringlist.
The User Exit capability can be used to extend the Help to whatever you need. As an example, I created this to meet my own needs:
Last year we explored these macros or features in some detail:
And these are just a few of the 140 general purpose macros that I use to enhance my own productivity!