14

From time to time I happen to M-! some_command just to find that the command runs longer than I expected and keeps my emacs frozen for long seconds. So I glaze at my frozen emacs and kick myself for not using M-& some_command and promise myself to use M-& next time. But M-! is in my muscle memory for decades… And of course there is Ctrl-G, but there are cases when breaking command and re-running it is not preferable (mayhaps it may break sth, mayhaps would be costly to rerun…).

Similar mistake in shell konsole is trivial to correct, Ctrl-Z, bg and job is running in the background.

Does there exist some similar trick in emacs - a way to turn currently running foreground (synchronous) command into backgroundized (asynchronous) one?

Note: in case it is impossible for default M-!, I am open to suggestions of how to rebind M-! into something else (what would be functionally equivalent apart from this trick).

  • 2
    You may be interested to know that simply adding an & to the end of a regular shell-command (M-!) will make it asynchronous. Of course, you must do this before running a command, but at least you can use the same keybinding. – nanny Jul 7 '15 at 17:24
  • 4
    You could always just remap M-! to async-shell-command. :-) Seems like the only thing you lose is getting the output in the echo area when it is short enough. – glucas Jul 7 '15 at 19:33
  • 1
    @nanny, in fact, that's all async-shell-command does. It adds an & to the end of the COMMAND string and executes shell-command. – Matthew Piziak Jul 23 '15 at 16:47
2

Does there exist some similar trick in emacs - a way to turn currently running foreground (synchronous) command into backgroundized (asynchronous) one?

I suspect no such trick exists. The problem is that the synchronous shell command (which is really call-process-region) blocks the emacs event loop. The only way to break it is to kill the process with a USR1 or USR2 signal or do C-g. (There may be other ways, but that's what I do).

This means there's nothing you can do because you don't have a way to invoke the trick, as Emacs does not process input while the event loop is stalled.


One thing you can do is simply swap the keys:

(global-set-key (kbd "M-!") #'async-shell-command)
(global-set-key (kbd "M-&") #'shell-command)
  • Rebinding M-! to async-shell-command makes partial sense, but: (1) I am not sure about M-1 M-! behaviour (command output to buffer) – simple fast cases work but what if the command is slower and I type sth? (2) in many cases I like the freeze until command finishes behaviour as it gives clear finish indication (some commands have no output…), therefore explicit keystroke „put to background” would be nicer (3) async leaves those Async buffers which must be reaped – Mekk Jul 28 '15 at 5:30
  • I am thinking whether some wrapper around async-shell-command would be possible to write (a function which would spawn async-shell-command, then wait for it's finish, react to Ctrl-G by aborting command and to some other keystroke by leaving it running but not waiting anymore, and reap Async buffer once done if output is empty or short). I am not sure how to do that waiting part… – Mekk Jul 28 '15 at 5:34

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.