5

Bob Glickstein describes in "Writing GNU Emacs Extensions", chapter 3, a way to advise scroll functions. (He suggests to make them reversible, so we have to save the state before scrolling.)

E.g. for scroll-up-command this advising is done like so

(defadvice scroll-up-command (before reversibilate activate compile)
   "If it wants to be reversible, it must save the former state."
   (save-before-scroll))

Well. I of course have to do this to all of the scroll commands. So I'd like to make a sequence of them, and want to advise them together.

(setq reversible-scroll-commands 
  [scroll-up-command 
   scroll-down-command 
   scroll-left-command 
   scroll-right-command])

(I use a vector to save 5 quotes.)

But now I'm stuck.

(mapcar 
  (lambda (fun-name)
    (defadvice fun-name (before reversibilate activate compile)
       "If it wants to be reversible, it must save the former state."
       (save-before-scroll)))
   reversible-scroll-commands)

will advise the (non existing) function fun-name four times, as defadvice is a macro, and doesn't evaluate fun-name.

Is there any way to do it?

(I'm using Emacs 24)

Drew
  • 29,895
  • 7
  • 74
  • 104
Falko
  • 1,028
  • 1
  • 12
  • 24
  • 1
    Today I learnt that `mapcar` works on vectors. Upvoted :) – legoscia Jul 05 '12 at 09:04
  • As of emacs 24.4.1 there is a new mechanism using `advice-add`, which is a function and uses a significantly cleaner syntax compared to `defadvice`; For a start anything anyone may need is documented in the docstring of the related function `add-function`, and there is no need for special constructs like `(ad-do-it)`. For this specific usecase it should be preferred. – kdb Aug 01 '15 at 10:00

1 Answers1

3

Untested:

(mapcar 
  (lambda (fun-name)
    (eval `(defadvice ,fun-name (before reversibilate activate compile)
             "If it wants to be reversible, it must save the former state."
             (save-before-scroll))))
   reversible-scroll-commands)

See the section about backquotes in the elisp manual.

legoscia
  • 39,593
  • 22
  • 116
  • 167
  • Just realised my previous version wouldn't work, so I added `eval`. You could remove it again if you put all of this in a macro. – legoscia Jul 05 '12 at 09:12
  • Cool. That was easier than I expected. Thank you! I nevertheless still don't understand your macro comment. – Falko Jul 05 '12 at 10:11
  • 1
    You could create a macro like this: ```(defmacro advice-my-functions (which-functions) `(progn ,@(mapcar (lambda (fun-name) `(defadvice ,fun-name (...) (save-before-scroll))) which-functions))```, and then you don't need `eval`. – legoscia Jul 05 '12 at 10:43