1

I would like to create a function that runs a command only after a previous command that takes some input from the user finishes running. In particular, I would like to write a function that runs a command after magit-pull:

(defun test ()
  (interactive)
  (call-interactively 'magit-pull)
  (read-key)
  (command)
)

The above function works only when magit-pull does not ask me for a password. However, when magit-pull asks me to enter my password in the minibufer, the above code won't work. I suppose I need to add some code that will only run "command" only after magit-pull is finished. Does anyone know of how I can implement this?

7
  • Add an advice to magic-pull. Check if there is a magit-pull-hook? Commented Feb 16, 2017 at 22:48
  • @John Kitchin : I didn't find a magit-pull-hook but, as expected, magit has other hooks available that I might try using. How would you use a hook in this case?
    – falsum
    Commented Feb 17, 2017 at 0:54
  • emacs.stackexchange.com/a/16558/7045
    – Emacs User
    Commented Feb 17, 2017 at 3:14
  • 3
    If there is no magit-pull-hook then it is not likely another hook would work for you. See stackoverflow.com/questions/5623208/… for a way to setup a git hook function that will probably work for you. Commented Feb 17, 2017 at 12:54
  • 1
    I suspect the real problem here is that magit-pull is calling some asynchronous code. I don't think it should matter whether or not the user is prompted for input. If the code is synchronous, the subsequent commands won't run until after the user makes their input.
    – Tyler
    Commented Feb 17, 2017 at 22:20

1 Answer 1

2

A general solution to "do something after another command" is to use advice, as suggested in the comments above.

(defun after-magit-pull ()
  "Some function to run after `magit-pull`.")
  (whatever))

(advice-add 'magit-pull :after 'after-magit-pull)

Whether this is the best way to accomplish your goal is a slightly different question. Using a git hook may be more appropriate, again as noted in the comments.

Update

Looking at magit-pull a bit more, using advice does not seem appropriate for this particular case. Magit starts git processes asynchronously and uses magit-process-sentinel to wait for the git process to complete so that it can do some additional work (like refreshing buffers). So :after advice on a command like magit-pull will probably run before the underlying git process actually completes.

To take some action after a git command finishes you might be able to use the magit-post-refresh-hook. I haven't tried this, but you could create your own command that adds an additional function to the post-refresh hook -- one that removes itself when it is done -- and then calling magit-pull.

3
  • My understanding is that this will advise magit-pull every time I call it. I guess I could use advice-remove at the end of the function to change that.
    – falsum
    Commented Feb 17, 2017 at 21:36
  • Unless I'm doing something stupid, the code above works when instead of using magit-pull I use an non-interactive function (e.g., bury-buffer). Do I need to change anything when using advice-add to apply to interactive functions?
    – falsum
    Commented Feb 17, 2017 at 21:42
  • 1
    The command bury-buffer is also interactive -- in elisp any command you can invoke via M-x is interactive, and advice works in either case. However, magit-pull is a bit more complicated: magit is starting git processes, sometimes asynchronously. In that case advice is not appropriate because the advised function will finish before the external git process returns.
    – glucas
    Commented Feb 18, 2017 at 16:00

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.