Saturday, January 22, 2011

PEM Editor tip: Go To Definition (Enhanced!)

'Go To Definition', introduced in Version 6.00, has been significantly enhanced in Version 6.50.

The 'things' for which you can 'Go To Definition' have gone beyond the original list of methods, properties, and objects to include creating new methods and properties, and finding PRGs, procedures, and functions, defined constants, classes, forms, and parent code. There is also a provision for customization using plug-ins.

The mechanics are simple:
  • Click on the name of the 'thing' (you can highlight it, if desired, but that is not necessary).
  • Initiate "Go To Definition", either by using the PEM Editor menu (in the VFP Main Menu) or by using the Hot Key (which you can assign in the Preferences form).

Note that Go To Definition will work in method code, PRGs, and also the Command Window.

Methods, Objects, and Properties
  • For methods, it will open up the method for editing, if there is custom code; otherwise it will open up a window showing all the parent code for the method.
  • For objects, it will act as if you selected the object in the form or from Document TreeView.
  • For properties, it will act as if you selected the object in the form or from Document TreeView and then highlights the property in the grid.
In the example below, the cursor is within the method name 'GridToExcelValue', and invoking 'Go To Definition' will bring up the code for that method.


In the example below, the WITH/ENDWITH construction is analyzed so that the definition being searched for is actually This.Parent.cmdSave.DoClick.  This analysis will include embedded WITH/ENDWITH constructions.

However, VFP does not provide any way to know what 'THIS' refers to in a editor window; that is, there is no information available that gives a reference to the object that the method is attached to. Thus, PEM Editor changes the title bar of any method that it opens in anticipation of any use of Go To Definition.

Finally, there is no way to determine what object is referred to by code like  loObject.Refresh(). Thus, at times, the wrong definition may be shown.

Creating New Methods or Properties

If the search for the property, method, or object was unsuccessful, you will then be prompted about whether you want to create a new property or method. This allows you to do so, using only a few keystrokes, without leaving the method you are editing.

Consider this example, when creating the first few lines of the Init method for a form:

Using Go To Definition pops up the following form:

Note that this is a direct but not necessarily complete way of adding properties or methods.  If you want to change the default value of the property, set the description, etc, you will still have to use the normal method of doing so; of course, you can still use this technique and come back to edit the property or method later.

PRGs, Procedures, Functions

In the sample code below, 'OpenTable' could be a PRG, or a procedure or function within a PRG; In any of these cases, Go To Definition will open the PRG for you (and, if it's a procedure or function within a PRG, will highlight the line where the definition starts).

Defined Constants

Similarly, selecting a name of a defined constant (created by #Define), whether the definition occurs in the current code or in (nested) #include files, will find and highlight that definition.

Note that for all of these possibilities, the active project, if any, is searched, along with the current path and settings for 'Set Procedure' and 'Set ClassLib', as appropriate

Thanks to Doug Hennig for idea for finding PRGS, procedures, functions, and constants, and also providing the code to implement it!


Using Go To Definition on either NewObject of Createobject will open the class named in the parameters that follow.  In the example below, using Go To Definition on 'NewObject' would open class 'ParameterX'; using it on 'CreateObject' would use it on class 'clsUpdateFoxCode'.


Using Go To Definition on the name of a form (that is, following 'Do Form') will open that form for editing..

Parent Code (DoDefault)

Using Go To Definition on DoDefault will open up a window showing all the parent code for the current method.

Customization Using Plug-Ins

If none of the searches described above are successful, PEM Editor will look for a plug-in which can do its own search for the selected 'thing'. It looks first for a file named PEME_GoToDefinition.PRG anywhere in the path. If this fails, it then looks for a file named GoToDefinition.PRG in the 'Live Plug-Ins' folder. (There is a commented sample GoToDefinition.PRG in the 'Sample Plug-Ins' folder, which can be copied to the 'Live Plug-Ins' folder and modified).

The PRG is called with three parameters -- the text being searched, the text (on the same line) preceding the text being searched for, and the text (on the same line) following the text being searched for. The PRG can then do, well, just about anything -- bring up a form, open a table, modify the code in the method, etc.

The sample, for instance, will assume that the text being searched for is a name, either of a cursor, table, or class.  If an alias by that name is already in use, it will open a form which has a browse window and a grid showing the table structure; or, if a table by that name exists, it will open the table and show the same form; or, finally, it will attempt to open and edit a class by that name (using one of the methods from _oPEMEditor.oTools -- a set of tools, soon to be documented, that is also part of this release).

(I welcome comments about other inventive uses for this plug-ins.)

Tuesday, January 18, 2011

PEM Editor Version 6.50 Alpha released

Version 6.50 of PEM Editor is now ready for testing; download it from   PEM Editor Version 6.50 Alpha 11

This version has already undergone considerable testing, and the expectation is that it will be released as a Beta version on VFPx within three to four weeks.

In the meantime, the remaining new features will be documented in this blog, and work will begin on creating the necessary documentation for its release on VFPx.


Monday, January 17, 2011

PEM Editor tip: Cross References screen (new feature)

This is a new feature in version 6.50.

The Cross References screen (see sample below) creates an analysis of all of the 'names' referenced in a PRG, method, or collection of methods.  These names are broken down into about a dozen different categories;  the TreeView on the left provides for navigation between the categories and the names within each category, and the grid on the right shows where the names are referenced.  Double-clicking on a row in the grid opens the indicated method and highlights the relevant line of code.

Invoking the Cross References Screen

For PRGs and single methods, the Cross References screen is accessible either from the PEM Editor menu in the VFP Main Menu, or by using a hot key (assigned in the Preferences screen).

For forms and classes, the Cross References screen may be applied to all of the custom methods for a class or an object, or for an object and all of its child objects.  The option to do so is found in the right-click context menu for the combobox.

Analysis / Categories in the TreeView 

The Cross References screen breaks the 'names' referenced in code into about a dozen distinct categories.  The 'names' actually include extended names, so that references to objects ('This.lblName.SomeProperty') or tables ('Customers.Name') are treated as single references.  Furthermore, references within WITH/ENDWITH blocks are resolved to point to the object named in the WITH statement.  (This even applies to embedded WITH/ENDWITH blocks).

The categories and their definitions are:
  • Global Assignments - simple names that are assigned values, but are not locals or parameters
  • Global References - simple names that are referenced, but are not locals or parameters
  • Tables/Cursors - references to names in VFP statements that indicate a table or cursor
  • Fields - references to names in SQL-Select statements
  • Forms - Do Form .....
  • Procedures/Functions -Calls to PRGs, or procedures or functions within PRGs.
  • Methods - Calls to methods
  • Property Assignments - references to properties or objects that are assigned values
  • Properties/Objects - references to properties or objects that are not assigned values
  • Parameters
  • Locals
  • Constants - compiler constants (#Define ...)
Warranty Information: This categorization cannot be perfect -- it is only at run time that VFP itself can properly identify which category any name falls into.  While the first two and last three categories are completely reliable (global assignments and references, parameters, locals, and compiler constants), the remainder cannot be, and so there are instances where names will be reported in the incorrect category.  For instance, 'Customers.Name' certainly looks like a reference to a field in a table, but 'Customers' could (conceivably) actually be an object reference.

The Grid

The four columns may be moved or resized them as desired; their size and order will be remembered for next time.

The grid displays one record for each line of code that a name is referenced on.  If you double-click on one of the records, the method/PRG will be opened and the line of code will be displayed.

There is a possible point of confusion when references are to code that is created on continuation lines.  The analysis of code in this screen treats code on continuation lines as a single line of code.  Thus, double-clicking to a reference in the grid will always highlight the first line in a set of continuation lines, even if the actual reference is to a later line in that subset.


There is a right-click context menu for the TreeView that allows for some customization:
  • You can select which of the categories are automatically expanded when the screen is first opened.  (By default, all categories are collapsed).
  • You can select which single category is initially selected when the screen is first opened (causing the references to the items in that category to appear in the grid.

Tuesday, January 4, 2011

PEM Editor tip: Source Code Control

This is a new feature in version 6.50.

If you are using Source Code Control, there is now an item in the Preferences file that allows you to specify if you wish to check out files using Source Code Control.

Whenever you try to open a file using PEM Editor, whether from one of the MRU lists or from one of the Open dialogs, you will first be asked whether you want to check it out; if not, the file will be opened in read-only mode.