Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 229
towi Avatar asked Nov 28 '13 20:11

towi


3 Answers

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)))))
like image 53
phils Avatar answered Oct 23 '22 01:10

phils


Not exactly an answer to your question, but to achieve the desired goal you can just mark the region and use align-regexp.

like image 2
tungd Avatar answered Oct 23 '22 01:10

tungd


Here's the code:

(defvar c-current-comment-col 30)
(defun c-set-comment-col ()
  (interactive)
  (setq c-current-comment-col (current-column)))
(defun c-comment-to-col ()
  (interactive)
  (beginning-of-line)
    (when (re-search-forward "//" (line-end-position) t)
      (backward-char 2)
      (let ((delta (- c-current-comment-col
                      (current-column))))
        (if (plusp delta)
            (insert (make-string delta ? ))
          (if (looking-back
               (format "\\( \\{%d\\}\\)" (- delta)))
              (delete-region
               (match-beginning 1)
               (match-end 1))
            (message
             "I'm sorry Dave, I afraid can't do that.")))))
    (next-line 1))
(global-set-key [C-f6] 'c-set-comment-col)
(global-set-key [f6] 'c-comment-to-col)

I've added a next-line call to the end. Now you can do C-f6 f3 f6 M-0 f4 to align until end of buffer.

like image 2
abo-abo Avatar answered Oct 23 '22 01:10

abo-abo