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?

  • Add an advice to magic-pull. Check if there is a magit-pull-hook? – John Kitchin Feb 16 '17 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 Feb 17 '17 at 0:54
  • 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. – John Kitchin Feb 17 '17 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 Feb 17 '17 at 22:20
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.

  • 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 Feb 17 '17 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 Feb 17 '17 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 Feb 18 '17 at 16:00

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.