I have a setup function that I want to run before I use pdb/gud to debug a Python script. I know about gud-mode-hook which runs after the debugger starts (too late) and change-major-mode-hook which, if I understand correctly, runs when you change major modes but before the major mode hook for the new mode (early enough, but will run in cases I don't want it to). How can I have a function called before a specific major mode is initialized?

So for my particular use case the flow would be something like:

M-x pdb -> (my-setup-function) is called -> pdb starts (i.e., it's hooks are run etc.)

So far I have tried doing this with major mode hooks pdb-mode-hook and gud-mode-hook but then the setup doesn't happen in time, and is only available the next time I run pdb. At one point I tried to do it with advice as well, but was not successful (potentially, because I did it wrong). This is what I tried (though I am confused as to whether or not this counts as advice):

 (add-function :before (pdb) #'my-setup-function)

...which I based on a snippet from the Emacs Lisp Reference manual:

(add-function :before (process-filter proc) #'my-tracing-function)

Obviously, I have not set this up right, and I get the message that (pdb) is not a valid place expression when I evaluate it. Even though (because?) the documentation for add-function is very detailed, I have a lot of trouble understanding how to use it properly.

  • 1
    Could you add a basic test to a function you add to the change-major-mode-hook? Eg, (defun my-setup-function () (when (eq major-mode 'python-mode) (do-my-setup-stuff))), and then (add-hook 'change-major-mode-hook #'my-setup-function).
    – Dan
    Commented Mar 4, 2016 at 15:41
  • @Dan I tried this, but couldn't get it to work. Shouldn't this call my-setup-function whenever you change from python-mode to another mode? Maybe I am misunderstanding the chain of events, but trying it this way it seems like my function just never fires period.
    – elethan
    Commented Mar 4, 2016 at 16:20
  • 1
    What about (defadvice :before ... Ugly, I know... Commented Mar 4, 2016 at 17:48
  • defadvice would be my answer as well. Why don't you share what you tried? Maybe someone will see what's wrong with it.
    – db48x
    Commented Mar 4, 2016 at 18:33
  • 1
    elethan: FYI your understanding of change-major-mode-hook is correct: major-mode still has its original (pre-change) value at this time. stackoverflow.com/a/19295380 might be of interest too.
    – phils
    Commented Mar 5, 2016 at 8:41

3 Answers 3


Do exactly what you want! That means define a function as follows and run this function instead of pdb.

(defun mypdb ()
  "Start `pdb' with my own setup."

That would be what the manual suggests in another situation:

If you simply want to change what a particular key does, it may be better to write a new command, and remap the old command’s key bindings to the new one (see Remapping Commands).

  • Thanks for this suggestion! It worked to solve my particular problem, but is also a nice pattern to know - for whatever reason, I never though about doing things this way
    – elethan
    Commented Mar 7, 2016 at 15:22

This seems to work. Apparently, defadvice is old-fashioned, and we're supposed to use advice-add instead.

(defun jk-advice ()
  (message "Kilroy was here"))
(advice-add 'python-mode :before #'jk-advice)
  • I am not sure why, but I was not able to get advice to work for my particular use case this time, though I am glad to have this as a straightforward, simple example to use in the future. Similar to using hooks, my setup function got called too late, and only took effect the second time I used the debugger. I went with @Tobias's solution, because that worked for me. Thanks for the "advice" on advice though!
    – elethan
    Commented Mar 7, 2016 at 15:19

Another solution is to use a more generic hook:

(add-hook 'prog-mode-hook
          (defun my-before-python-mode()
            (when (eq major-mode 'python-mode)
              (message "running before python"))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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