Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap align-regexp for specific regexp in emacs

Tags:

emacs

elisp

I often use align-regexp with the regexp " [^ ]+_" on a region. So I thought I'd define a function for it so I could bind it to a key:

(defun align-members ()
  (interactive)
  (align-regexp " [^ ]+_"))

But emacs complains align-regexp takes three parameters. Looking at the docs, I see it takes BEG and END. I'm not sure how (interactive) stuff works in emacs, but from reading the documentation I gather I should be doing this:

(defun align-members (BEG END)
  (interactive "r")
  (align-regexp BEG END " [^ ]+_"))

But emacs then complains somewhere deep in align-regexp's call stack that it expected integer-or-marker-p and instead got nil. What am I doing wrong?

like image 774
Joseph Garvin Avatar asked Feb 14 '12 18:02

Joseph Garvin


2 Answers

You should write is as the following

(defun align-members (BEG END)
  (interactive "r")
  (align-regexp BEG END (concat "\\(\\s-*\\)" " [^ ]+_") 1 1))

or a bit simpler

(defun align-members (BEG END)
  (interactive "r")
  (align-regexp BEG END "\\(\\s-*\\) [^ ]+_" 1 1))

To understand it, take a look on a align-regexp source, here there is a part of it.

(interactive
 (append
  (list (region-beginning) (region-end))
  (if current-prefix-arg
      (list (read-string "Complex align using regexp: "
                         "\\(\\s-*\\)")
            (string-to-number
             (read-string
              "Parenthesis group to modify (justify if negative): " "1"))
            (string-to-number
             (read-string "Amount of spacing (or column if negative): "
                          (number-to-string align-default-spacing)))
            (y-or-n-p "Repeat throughout line? "))
    (list (concat "\\(\\s-*\\)"
                  (read-string "Align regexp: "))
          1 align-default-spacing nil))))

As you can see:

  • it adds a string "\\(\\s-*\\)" to your regex
  • it sets 1 and align-default-spacing to the optional parameters
like image 177
Oleg Pavliv Avatar answered Nov 16 '22 12:11

Oleg Pavliv


Oleg's answer is fine.

The reason that align-regexp fills in details for you when called interactively is that you should be able to do the most useful things with as few key-strokes as possible. If you need to assert more control then use the C-u prefix.

This is a common design theme for Emacs commands.

Now when you call align-regexp programatically, there is no need to offer you a short-cut, since presumably the programmer wants full control by default.

In the future, when you convert a task into an interactive defun, use C-x esc esc to see how the command received your input after they went through the interactive forms.

In this case, you should see something like:

(align-regexp 185 320 "\\(\\s-*\\)" [^ ]+_" 1 1 nil)
like image 30
event_jr Avatar answered Nov 16 '22 12:11

event_jr