0

I want to advise org-edit-special so that a function runs before Emacs enters org-src-mode. I am not particularly tied to org-edit-special. If there is a hook like org-src-mode-hook (but that triggers before org-src-mode runs, that would be perfect.

So I have the following code:

#+BEGIN_SRC emacs-lisp

(defun my-function ()
  (message "bingo!"))

(add-function :before (org-edit-special) #'(lambda () (my-function)))

#+END_SRC

When I C-c C-c this block, I get user-error: No special environment to edit here. Can you see the mistake?

3
  • Please say what you mean by "to work". What do you expect, and what do you see instead?
    – Drew
    Apr 26 '20 at 17:52
  • Drew thanks. I have added more to my post. Please let me know if you have additional questions. Best -Adam
    – Adam
    Apr 26 '20 at 18:25
  • 1
    (org-edit-special) is the result of calling the function org-edit-special - that's probably not what you want. Also, you should probably use advice-add (see the manual), not add-function.
    – NickD
    Apr 26 '20 at 20:26
1

You port the defadvice approach from your own answer to nadvice.el like so:

#+BEGIN_SRC emacs-lisp
(define-advice org-edit-special (:before (&optional arg) my-big-advice)
  (message "bingo!"))
#+END_SRC

define-advice is largely analogous to the older defadvice.

11
  • Thanks @phils - I find this topic extremely confusing, in particular because there appears to be no consensus in the documentation on how to get this done. Can you speak to the advantages/disadvantages of each approach? What is the benefit of using nadvice.el versus the one I outlined above? And how about the approach that NickD mentioned, using advice-add? Also, in your code, if the optional args are not needed, do you still include the parentheses? I.e., (define-advice org-edit-special (:before () my-big-advice) (message “bingo!”))
    – Adam
    Apr 27 '20 at 8:05
  • I'll just add that as nil and () are the same thing in elisp, you could indeed use ().
    – phils
    Apr 27 '20 at 11:22
  • Using nadvice.el tends to be strongly recommended nowadays. Instances of old advice in Emacs core and in ELPA tend to get re-written. It's probably best to get familiar with nadvice. Using the define-advice macro is the easiest way to port old advice for the most part, and personally I think it's the most readable of the options provided by the nadvice library (certainly if you're familiar with the old advice library); so if it suits your purpose then I would suggest using it. Entirely up to you, though.
    – phils
    Apr 27 '20 at 11:35
  • @phils I just tested this out (define-advice org-edit-special (:before () my-big-advice) (message "bingo!")). After evaluating, with point on an R src block, I ran org-edit-special and received the following error: Wrong number of arguments: (lambda nil (message "bingo!")), 1. Any ideas?
    – Adam
    Apr 27 '20 at 20:59
  • @Adam I just meant that if it was valid to use nil then, in those cases, you could alternatively use () because the two things are the same. My impression is that nadvice requires you to state the argument list, because it uses it -- so if it's not empty then you can't say that it is without breaking calls to the function. In the case of org-edit-special, per the code in the answer, the appropriate value is (&optional arg).
    – phils
    Apr 27 '20 at 22:10
0

I figured it out. Here is the correct form:

#+BEGIN_SRC emacs-lisp

(defun my-function ()
  (message "bingo!"))

(defadvice org-edit-special (before my-big-advice activate)
  (my-function))

#+END_SRC

And here is a good tutorial on advising functions for anyone else who runs into this.

Looking at our revised code from left-to-right: defadvice is self-explanatory. org-edit-special is the function we are advising. before means we want our advice to happen first. my-big-advice is the name of our advice (we could have called this foo-bar if we wanted). And activate tells Emacs to make this work now.

2
  • 1
    defadvice is the old way of advising functions and although AFAIK not deprecated (yet?), it's probably a good idea to use the new mechanisms in new code. See the manual.
    – NickD
    Apr 26 '20 at 22:54
  • @NickD This works for me without issue on Emacs 26.3. But if you would like to propose your own revised and updated code, please feel free.
    – Adam
    Apr 26 '20 at 23:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.