Surround With Template: add dual code template

The Surround with Template refactoring acts like a (parameterizable) dual code template. One code snippet is inserted before and the other after the selected code (or current line). The selection is (optionally) indented. It is commonly used to add "if - then - begin - end" or "try - finally - end" statements around existing code. Snippets can be selected from a customizable list and can use context sensitive macros.

An example

Suppose you have this code:

function Price(Quantity, ItemPrice: Integer): Extended;
begin
  Result := (Quantity * ItemPrice) -
            (MaxInt(0, (Quantity - 500)) * ItemPrice * 0.05);
end;

If you realize you need an if then else statement around this function, you select the code (in the case of a single line like in this example you do not need to select the code at all), press Ctrl+Shift+A...

Surround Popup

...and after selecting the "if then else" template from the pop up menu...

Refactor

...the resulting code shows the two snippets inserted before and after the current line and the indented line.

function Price(Quantity, ItemPrice: Integer): Extended;
begin
  // snippet inserted before selected text and cursor positioned at |
  if | then Refactor Result
  begin

    // Selected text indented with one block (template option).Refactor Result
    Result := (Quantity * ItemPrice) -
              (MaxInt(0, (Quantity - 500)) * ItemPrice * 0.05);
  // snippet inserted after selected text
  end Refactor Result
  else
  begin

  end;
end;

Similarly, you could add a try finally statement around this code by selecting the "try finally end" template:

function Price(Quantity, ItemPrice: Integer): Extended;
begin
  try Refactor Result
    Result := (Quantity * ItemPrice) -
              (MaxInt(0, (Quantity - 500)) * ItemPrice * 0.05);
  finally; Refactor Result
    |.Free;
  end;
end;

Indentation options

The indent level can be defined template. Additionally Surround with Template supports unindenting the two templates rather than the existing code. This is useful for adding begin end (or block { } ) pairs around existing statements. For example:

  if Condition then
    DoSomething; // place cursor on this line

Applying a begin / end template with option unindent snippets enabled, results in:

  if Condition then
  begin
    DoSomething;
  end;

Note that begin and end have one indention level less than the existing code.

Single line style templates

In addition to the multi line style as shown in the above examples, the Surround With Templates refactoring has a Single Line style. In Single Line style the prefix and postfix snippets are inserted immediately before and after the selected text or, if there's no selection, before and after the cursor position. No extra new lines are added. The option Auto Select Token automatically selects the entire token at the cursor position - which makes it easier to apply templates like FreeAndNil and MessageDlg in the following examples.

Examples:

A single line style template FreeAndNil defined can then be used like this:

  FItems // before applying the template

  // after applying the template:
  FreeAndNil(FItems); Refactor Result

Similar a single line MessageDlg can be applied like this:

  'This is a message' // before applying the template

  // after applying template:
  MessageDlg('This is a message', mtInformation, mbOKCancel, 0); Refactor Result

Defining templates

The ModelMaker Code Explorer Surround templates are organized in a user definable hierarchy and can be created with the Surround Snippets Editor (invoked) that's displayed here:

Template Editor

Templates snippets can use the predefined and context sensitive macros <!classname!> and <!membername!>. When applied these will expand to the class and member name at cursor position. Check the default snippets file for an example.