What Are Snippets?
Clips or snippets are pieces of code that are either difficult to remember or often used with minor tweaks. Developers look for ways to leverage their IDE to write code snippets once and then paste them into an editor whenever / wherever they are needed. In Classic the IDE facility is called the Clip Window. In the .NET IDE the facility is called Snippets. The process of creating and using Snippets in .NET is quite different from its Classic counterpart. The purpose of this article is to familiarize a Classic developer with the .NET IDE Snippet facility and help increase their .NET coding productivity by guiding them through the process of defining and using .NET code Snippets.
Classic Clips: A Review
Figure 1 shows the Classic Clip Window displaying two snippets. Table 1 summarizes the use and benefits of Classic Clips
Figure 1: Classic Clip Window
Introducing VS .NET Snippets
Visual Studio implements Snippets differently than Classic. Table 2 summarizes their capabilities and features
Predefined System Snippets
Out-of-the-box PowerBuilder contains a set of predefined System snippets. System snippets are located in the PowerBuilder installation folder tree. You can view and modify their source code as needed, but any changes you make will be lost when you upgrade your PowerBuilder IDE. As you can see from Figure 2, editor support for what used to be called "paste special à statement," the familiar control structures, is implemented as insert snippets. Figure 3: shows how to insert a system snippet from the menu system. Figure 4 shows a System snippet list in the editor.
Figure 2: System snippets
Figure 3: Inserting a system snippet
Figure 4: System snippet list in the editor
Placing a Snippet
You can use the Shortcut chords Ctrl-K, Ctrl-X or right-mouse button or Edit Menu to have the system present you with a list of snippets to choose from. Note from Figure 5 that you can choose from either developer or system snippets (when both are present).
Figure 5: Snippet Folders choice
When you select a snippet, the code is placed in the editor at the cursor location and any variables defined in the snippet are assigned their default values. Variables in the snippet are highlighted. Hovering the mouse over a variable shows their tooltip. This a cue for you to adjust the variable value as needed (see Figure 5a).
The shell provides a snippet manager that you can use to add and delete snippet files from within the IDE. You can open it using the chords Ctrl-K, Ctrl-B or the Tools à Snippets Manager menu. Although you can't define new snippets using this utility, you can import snippets created by a fellow developer. Note there is no magic to this utility. You can just as easily copy or move files into a snippets folder using Windows Explorer. Exercise caution though as you can accidentally remove your System snippets! They are not moved to the Recycle Bin. Figure 6 shows the Snippets Manager.
Figure 6: Snippets Manager
Defining a Snippet
A real benefit of Snippets is that you can define and use your own code snippets to automate your own repetitive tasks or to support your memory when writing code. In this section I'll show you how to define a .NET snippet.
Snippets are defined as XML files with a .snippet file name extension. Their structure and content adhere to the Code Snippet XML schema located at http://msdn.microsoft.com/en-us/library/ms171418(v=VS.80).aspx
The snippets you define are stored in the C:\Users\<current user>\Documents\Sybase\PowerBuilder 12.0\PowerBuilder .NET\Code Snippets\PowerScript\My Script Snippets folder. As your collection of snippets grows, you can organize them into subfolders. The IDE shows your snippets by folder. You can easily navigate the folders to locate the snippet you want using the mouse or tab key. Alphabetic type ahead and keyboard selection is also supported.
Although, you can create and edit snippets by following the schema and entering valid XML using any text editor, by far the easiest way to get started writing snippets is by downloading and using a Snippet Editor. I found a great open source one from Bill McCarthy, a Microsoft MVP, at http://snippeteditor.codeplex.com/. Although the editor is MS Visual Studio-centric and doesn't see the isolated shell, I discovered a couple of workarounds that made it work with PowerBuilder. First, to allow access to the editor as part of my Visual Studio experience, I added it to my tools menu as an External Tool. Now I don't have to leave PB to access it. Figure 7 shows my Tools menu after adding the external tool.
Figure 7: Snippet Editor on Menu
Next, the Snippet Editor is MS centric and tied to the MS VS keys in the Registry. It automatically loads C# and VB snippets and doesn't see the isolated shell keys; I had to add PowerBuilder's My Snippets folder to the folder view. The tool provides an "Add Path" context menu item that supported my action. (Unfortunately it doesn't remember added paths, so you have to do this every time you use the tool.). Figure 8 shows my folder view after adding the folder.
Figure 8: PB User Snippets in Snippet Editor
Last, the editor only supports language attributes for Microsoft languages. Whenever you create a new snippet you will need to edit the generated snippet file with WordPad and change the language attribute of the Code element to PowerScript <Code Language="PowerScript". If you skip this step, PowerBuilder will not recognize the snippet and you won't see it listed it in the snippet choice list in the Painter. Fortunately, subsequent edits to the body of the snippet in the Editor don't revert the language designator change, so this is a one-time patch. (I dropped an email to the tool author asking him to add PowerScript support. The tool is open source; if you're a C# pro, you might consider modifying the code and submitting the change.)
Figure 9 shows the edit fields in the Snippet Editor and their effect on the Snippet choice list and resulting pasted code. Table 3
briefly explains each.
Figure 9: Annoted picture of Snippet Editor fields
Conclusion and Limitations
The product engineers have done a reasonable job of providing support for member body literal and object type Snippets with or without parameters. Once you spend a bit of time configuring your own snippets and getting used to working with them in the editor, you will find the Snippet feature is a beneficial productivity enhancement.
There are limitations in the current implementation that you should be aware of. First, there is no migration path for Classic clips into the .NET IDE. You'll have to redo all your Classic clips as Snippets. Copy and paste from Classic into the Snippet Editor should do the trick. (I added an action item to my ToDo list to build a conversion utility. Not sure when I'll get to it though.)
Next, the Sybase engineers have provided equivalent functionality to that in Classic without implementing the advanced capabilities present in the Snippet specification. For example, the specification provides for elements that allow you to specify which references and imports (usings) a code object needs - these do not work in PB. If your snippet code contains code objects in a namespace or assembly, you will have to add those references and usings manually.
The specification supports snippets in three scopes: (1) Class Declaration, snippets that define an entire class; (2) Member Declaration, snippets that define an event handler or function routine; and (3) Member Body, snippets inserted into existing member. Of the three, only member body snippets are supported. This is roughly equivalent to Classic clips.
I'd like to see tool support for imports and references; having it would make coding calls to methods in assemblies and web services easier; I'd be less prone to forgetting or using a reference. I'd also like to see support for Class and Member snippet definition. Having it would increase my productivity by making implementing common CCUOs as well as function and events in all object types into a template-generated activity.
<Description>Basic DW Update Block</Description>
<ToolTip>Transaction Object Reference Name</ToolTip>
<Code Language="PowerScript" Kind="method body" Delimiter="$">