I have a love-hate relationship with AppleScript. The syntax is annoying, string manipulation is a pain, it is hard to debug, and scripts are stored in a binary format. But I would be incredibly sad if AppleScript went away. Interacting with other programs gives you a lot of power.
Following the advice of Bram Moolenaar, I’ve been monitoring tasks that I repeat often which take longer than they could. I noticed that when writing Latex, I often need to change then name of an environment while editing. For example, I might have
Then I decide that I need to change it to an
align* environment or just remove the star from the
equation* environment, which means I have to edit both the
begin tag and the
end tag. Changing both at once will probably only save a few seconds, but those few seconds are saved over and over again, and typing becomes a little less repetitive and a little more productive.
Here is where AppleScript comes in. I need to get the location of the cursor, determine which environment contains it, prompt the user for a new name, make the change, and put the cursor back where it belongs.
The first two of these I could do with Python. BBEdit uses environment variables to pass information about the cursor to cursor position to shell scripts. Python would have no problem doing the searching. But prompting the user and making sure the cursor doesn’t jump due to a change in the length of the document require AppleScript.
The “Change environment” script is a new addition to my Latex BBEdit package, which incorporates lots of Latex related scripts and clippings I’ve made and collected. I’ll explain some of the useful details of the script in this post.
You can use AppleScript to get the number of characters between the beginning of the document and the current cursor location:
You can move the cursor around with the command
select insertion point. In my case, if I replace
align*, I would like to shift the cursor
left by 3, so that its relative position stays the same.
To figure out which environment contains the cursor, I search backwards from the cursor for a
begin, then forward from that point for an
end, and then I check to make sure that the cursor is between the two. If it is not, I repeat the process until it is. There is a little extra logic in there to deal with possible nested environments.
A basic search looks like
The result is an AppleScript “record” (dictionary) with keys
found (was there a match?),
found object, and
found text. The
found object has properties like
Notice the double escaped backslashes. AppleScript interprets each pair of backslashes as a single backslash, and BBEdit does the same. This sort of thing used to drive me nuts, but I’m better at it now.
Of course, things don’t really get exciting until you do a grep search. This one searches backwards from the cursor for any sort of
begin and captures the name of the environment.
Here is how you change just one piece of the document