While implementing a change to the OpenVOS kernel, I found myself faced with the task of modifying about 150 files. This meant reserving them in the source control system, updating the copyright, adding a modification history line, and making the code change (which was to add a #include pre-processor statement. I knew that if I simply started doing this work by hand it would take forever. So I used a couple of shortcuts to get the job done faster.
The first trick I used was to create a list of all of the files that I needed to edit. I used our source control system to generate that list, but it wasn’t in a form I could easily use. So I captured the output of the command and used an emacs keyboard macro to massage it into a command macro. If you have never used an emacs keyboard macro before, you are in for a treat. If you have used them, you can skip over this part and go on to the next trick.
The emacs editor has a command that can record editing requests as they are entered. In both OpenVOS emacs and GNU emacs, the command to start recording commands is “ESC-(“. Every command that you type after that is executed and recorded. When you are ready to stop recording, you type “ESC-)”. You can execute the keyboard macro a single time by typing “ESC-m” (in OpenVOS emacs) or “^X-e” (in GNU emacs). Keyboard macros are great for editing highly repetitious files, which was exactly the case I faced. Here’s a simplified example, using a list of the POSIX functions that start with the letter “a”:
Files: 17, Blocks: 19
r 2 abort.c
r 1 access.c
r 1 adjtime.c
r 1 aio_cancel.c
r 1 aio_error.c
r 1 aio_fsync.c
r 1 aio_read.c
r 1 aio_return.c
r 1 aio_suspend.c
r 1 aio_write.c
r 2 alarm.c
r 1 altzone.c
r 1 asctime.c
r 1 asctime_r.c
r 1 asprintf.c
r 1 assert.c
r 1 atexit.c
I needed to edit this buffer so that each line looked like this:
where fixup.cm was a command macro that would accomplish several tasks (more on this later). So I deleted the first few lines so that all that was left in the emacs buffer was the repetitive list of files. With my cursor on the start of the first line, I typed “ESC-(” to start recording, and then proceeded to edit the line to delete the first two “words” and replace them with the string “fixup”. I then left the cursor at the start of the next line, and ended the recording with “ESC-)”. Here’s the exact sequence I typed (using OpenVOS emacs key bindings):
ESC-( ESC-d ESC-d fixup ^N ^A ESC-)
Now the first line has been edited and my cursor is on the start of the 2nd line. Since everything worked OK, I then typed:
to edit the rest of the file. Since the buffer has fewer than 99 lines, this macro runs until it hits the end of the buffer, and then stops. Then I wrote out the buffer as “fixup_all.cm”.
The next step was to write the “fixup.cm” command macro. I decided that it would update the copyright, update the modification history, and then enter emacs so I could manually add the #include statement. While I was still in emacs, I created a new keyboard macro to insert the necessary #include statement at the cursor:
ESC-( #include “sample.h” ESC-)
Since I would be entering and exiting emacs for each file, I had to permanently save this macro and bind it to a key. The emacs request to save the current keyboard macro as a permanent macro is “save_macro” but it has no default key binding. To execute it once, type
and it will prompt you for the name to associate with this new macro. I called my macro “add_include_file”. I then edited my start_up.emacs file to contain the line:
set_key ^z-i add_include_file
So now I quit out of emacs and restarted it, so that I could be sure the set_key statement would work properly. I then entered the text of fixup.cm. I used the line editor because I thought it was the easiest way to update the modification history.
!line_edit &file& -no_backup –no_verbose
l/End of modification history/
/* Modified 10-05-17 by Paul Green to … */
This macro will add (or update) the copyright information, add the modification history line just before the comment that we use to mark the end of the modification history section, and then enter emacs so I can manually find the place to add the %include statement.
I now have two command macros: “fixup_all.cm” and “fixup.cm”. The former invokes the latter once for each file that has to be modified. I then started my marathon editing session by typing “fixup_all” and all I had to do was to find the place to insert the #include statement, type “^Z-i”, write the file out, and quit. The macros did the rest of the work.
Even with the time it took to write the macros, I still saved a lot of time and effort (and probably a few typos) by creating these editor and command macros. It also turned a dreary task into a much more interesting task.
I hope you find this information useful. That’s all for now.