In Part 1,
we went over how to create a macro from scratch, load it and bind it to
a key. We also went over some basic macro functionality like inserting
a new line of text and determining which language we are working in. I
thought it would be useful to stick with the theme of writing a macro
that could insert some useful code. In this blog, we’ll write a macro
that surrounds the currently selected block of code with some simple
code that reports how long the block takes to execute. It’s sort of a
poor-man’s performance tuning, and everyone needs to do it from time to
time when they need to determine how long various sections of code take
to execute, but don’t want to instrument the whole code base.

Working with selections

The very first thing I realized when I sat down to do this was that
I’d need to get the bounds of the current selection, and I’d never
worked with selections before. Whenever I hit an area that I’m
unfamiliar with, the first place I go is the API documentation. To get there, you can click Help > Contents, and then click API Documentation at the bottom of the contents list. Next, select Macro Functions By Category and you will be taken to a categorized list of the documented Slick-C functions. I scrolled down and found the Selection Functions
category in the list, clicked it, and started looking through that list
for potentially useful ways to get the bounds of the current selection.

Right away, I noticed _get_selinfo() and it looked like a perfect
fit. The problem that I discovered though, is that _get_selinfo()
doesn’t provide line numbers for the current selection, only column
numbers, which made it useless for the information I needed. I then
decided to look at how other macro functions were using _get_selinfo(),
so I right clicked it and selected “Goto reference to _get_selinfo” which lists all of the places in the macro code where it’s called. You can also use the find-refs
command for this. This led me to other code that used _begin_select()
and _end_select(), which I had passed over in the help originally
because they sounded more like actions than a way of getting selection
information. My strategy for getting the line range was to call
_begin_select(), which places the cursor on the first line of the
selection, and insert a line of code to get a timestamp. I would then
do the same thing with _end_select() and insert the code to get a second
timestamp and report the difference.

Writing the macro

We’ll start by beginning a new macro file the same way we did in Part 1, and we’ll call it “insert_debug_timer.e”. Using our selection strategy, we can write the following macro code:

After loading this, you can select some text in your editor, run insert-debug-timer()
and your selection will be surrounded by the text “This is the
beginning” and “This is the end”. Success! Now we can move on to
inserting the actual code that will do the timing. There will be two
parts to this, the code that gets inserted before the selection, and the
code that gets inserted after the selection. I first made a throw-away
command to test what the code might look like (in Slick-C):

Let’s start with the code that gets inserted before the selection.
We know that we’re going to have to detect which language we’re in and
insert something different based on that, just like we did in Part 1. I
didn’t want to pollute the code in the insert_debug_timing()
command, so I decided that I’d make a separate function to insert the
“before” code. This function will take the indentation text as a
parameter and directly insert the text at the current line.

Next we can write the second function, which is basically the same as
this one, except that it inserts the code to take a second timestamp,
diff the two timestamps and report the time difference. We now replace
the lines in insert_debug_timer() with calls to these two
functions. We now have a command that takes the current selection (or
the current line if there’s no selection) and wraps it with timing code.