Emacs, scripting and anything text oriented.

Save a macro as a function in emacs

Kaushal Modi

I am in the process of converting traditional verilog test benches to SystemVerilog UVM test benches. As per the UVM methodology, it is recommended to use `uvm_info instead of $display statements so that the info statement encodes a Message ID and Message Verbosity along with the message required to be printed.

I won’t go in more detail about UVM and verilog as this post is about how I can save a macro that I use very frequently into an elisp function.


  • Regex Search Expression
\$display(\(.*?\));\(.*\)
  • Replace Expression
`uvm_info("REPLACE_THIS_GENERIC_ID", $sformatf(\1), UVM_MEDIUM) \2

As it can be seen that it very time consuming if I need to type these search and replace expressions every time (even if I use the M-n and M-p key bindings during the query-replace-regexp).

So the solution is to save the search-replace operation into a macro and then save that macro as an elisp function.

  1. Select the region you want to do the search-replace.
  2. Start recording macro start-kbd-macro. I have bound this to C-F4.
  3. Do the above search-replace and use ! to force search-replace in the whole region.
  4. Stop recording macro kmacro-end-or-call-macro. I have bound this to F4.
  5. Do M-x kmacro-name-last-macro and give the macro a descriptive name. You will then be able to call that macro again by doing M-x and the macro name you picked. For this example, I named the macro uvm-convert-display-to-uvm_info.
  6. Now save this macro as a function to a file that you load during your emacs initialization1. To do that do M-x insert-kbd-macro and select your named macro to be inserted there.
  7. Now save that file and your named macro will be loaded in all of your future emacs sessions.

The inserted uvm-convert-display-to-uvm_info function definition looks like this:

(fset 'uvm-convert-display-to-uvm_info
   (lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([3 113 92 36 100 105 115 112 108 97 121 40 92 40 46 42 63 92 41 41 59 92 40 46 42 92 41 return 96 117 118 109 95 105 110 102 111 40 34 82 69 80 76 65 67 69 95 84 72 73 83 95 71 69 78 69 82 73 67 95 73 68 34 44 32 36 115 102 111 114 109 97 116 102 40 92 49 41 44 32 85 86 77 95 77 69 68 73 85 77 41 32 92 50 return 33] 0 "%d")) arg)))

Now I can simply M-x uvm-convert-display-to-uvm_info the next time I need to replace those $displays with `uvm_infos.


  1. I save my verilog related macros to my setup-verilog-mode.el↩︎