Search code examples
emacscommentsalignmenttext-formatting

How to automatically align comments in different pieces of code?


I have to do a very specific task to re-do over and over again and would like to have it put permanently in my .emacs file. But I am not versed enough in emacs-lisp to manage it:

  • Keystroke-1, say F8
    • remember the current cursors' column position in, say, xtab
  • Keystroke-2, say F9 while cursor is in some other line:
  • find leftmost string // in current line, if none is there, beep and stop
  • insert as many spaces so the // gets to previously remembered column xtab, or do nothing if cursor is already beyond xtab
  • search-forward for next // and place the cursor on it

I managed to assign it to a temporary keyboard macro, but have to re-record it for every changing xtab value.

The ultimate goal is that I want to align the comments in different pieces of code easily, from

int main() {     // the enty function
    int x = 100; // my new variable
    for(int i=1; i<2012; ++i) { // loop a lot
        x -= i;
    } 
} // end of all things

to

int main() {                    // the entry function
    int x = 100;                // my new variable
    for(int i=1; i<2012; ++i) { // loop a lot
        x -= i;
    } 
}                               // end of all things

Any idea how I can automate this? What do I have to put in my .emacs-file to archive this -- or similar?


Solution

  • As tungd said, align-regexp is good for this sort of thing.

    (defun my-align-comments (beginning end)
      "Align instances of // within marked region."
      (interactive "*r")
      (let (indent-tabs-mode align-to-tab-stop)
        (align-regexp beginning end "\\(\\s-*\\)//")))
    

    Which is like the interactive call:
    M-x align-regexp RET // RET

    Or for a more language-agnostic version:

    (defun my-align-comments (beginning end)
      "Align comments within marked region."
      (interactive "*r")
      (let (indent-tabs-mode align-to-tab-stop)
        (align-regexp beginning end (concat "\\(\\s-*\\)"
                                            (regexp-quote comment-start)))))