3

Now that I know how to right-align columns of numeric values in Emacs, I have two issues with this solution:

  • it is hard to remember
  • it is not flexible

For instance, it doesn't work when some of the values in the first column contains a number.

And unfortunately it inserts tabs.

Now I use rectangle functions (C-xrk) quite a lot. That made me think: would it be possible to have a function that right-aligns all text in the selected rectangle?

Community
  • 1
  • 1
Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
  • Here's how to enforce a no-tabs policy for alignments: http://stackoverflow.com/questions/915985/in-emacs-how-to-line-up-equals-signs-in-a-series-of-initialization-statements/8129994#8129994 – phils Jun 06 '12 at 14:38
  • And I should add that `align-regexp` and the whole `align` library is extremely flexible, so it's more a matter of defining the correct regexp or rules for the job at hand. – phils Jun 06 '12 at 15:00
  • @phils It comes down to me being able to understand/remember what rectangles do and not what `align-regexp` does. – Michel de Ruiter Jun 06 '12 at 20:13

1 Answers1

9
(defun right-justify-rectangle (start end)
  (interactive "r")
  (apply-on-rectangle (lambda (c0 c1)
                        (move-to-column c1 t)
                        (let ((start (- (point) (- c1 c0)))
                              (end (point)))
                          (when (re-search-backward "\\S-" start t)
                            (transpose-regions start (match-end 0)
                                               (match-end 0) end))))
                      start end))

To avoid Tab, customize the variable indent-tabs-mode.

Edit:

Here is a version that deals with indent-tabs-mode more reasonably:

(defun right-justify-rectangle (start end)
  (interactive "r")
  (let ((indent-tabs-mode nil))
    (apply-on-rectangle (lambda (c0 c1)
                          (move-to-column c1 t)
                          (let ((start (- (point) (- c1 c0)))
                                (end (point)))
                            (when (re-search-backward "\\S-" start t)
                              (transpose-regions start (match-end 0)
                                                 (match-end 0) end))))
                        start end))
  (when indent-tabs-mode (tabify start end)))
Community
  • 1
  • 1
huaiyuan
  • 26,129
  • 5
  • 57
  • 63
  • 1
    ...slow clap... so much goodness in this answer `apply-on-rectangle` `\\S-`, `transpose-region`. – event_jr Jun 06 '12 at 14:49
  • Agreed; very nice. You will need to `(require 'rect)` though. – phils Jun 06 '12 at 14:51
  • Actually, this is unreliable with `indent-tabs-mode` true, as the mixture of tabs and spaces created at the end of the line with `move-to-column` may not be appropriate for transposing. – phils Jun 06 '12 at 15:25
  • Along with `(global-set-key "\C-xr\r" 'right-justify-rectangle)`, this is **exactly** what I have always needed! – Michel de Ruiter Jun 06 '12 at 20:26