1

Is the following sort of shortcut macro possible to implement?

(defmacro region-end-beg ()
 "Replacement for '(region-end) (region-begin)' in source code"
 (...))

So that

(buffer-substring  (region-end-beg))
(setq region-length (- (region-end-beg))

Can be used as a shortcut for

(buffer-substring  (region-end) (region-beginning))
(setq region-length (- (region-end) (region-beginning))

This example is semi-contrived. What I'm interested in is there is a general technique to make this kind of macro in lisp (particularly elisp).

Drew
  • 75,699
  • 9
  • 109
  • 225
user26109
  • 11
  • 1
  • There's no way to have a single macro call expand into two expressions. – npostavs Nov 23 '19 at 04:42
  • I don't think a macro can expand to more than one separate s-expression. You could, with some effort, make a code-walking macro `(with-region-end-beg ...)` that would replaces all occurences of `(region-beg-end)` in the code indicated by `...` with `(region-end) (region-beginning)`. – Omar Nov 23 '19 at 17:21

1 Answers1

2

Not exactly. Function buffer-substring requires two arguments. Function - will accept a single argument, but in that case it just returns the negative of that numeric argument. What you want to do is, in effect, apply such functions to a list of arguments. You can use higher-order function apply to do that.

What you can do, if you want, is have a macro or an ordinary function return a list whose elements are the values of (region-end) and (region-beginning), using, say, (list (region-end) (region-beginning)).

But there's no reason to use a macro to do that. As a general rule, use an ordinary function instead of macro, whenever that does what you need.

With the list constructed by your function, you would then use apply to apply buffer-substring and - to the list returned by your function. That applies those functions to the list elements as arguments.

(defun region-end-beg ()
  `...`
  (list (region-end) (region-beginning)))

(apply #'buffer-substring (region-end-beg))

(apply #'- (region-end-beg))
Drew
  • 75,699
  • 9
  • 109
  • 225