Automatically stopping a process when exiting Emacs - emacs

I am trying to stop the simple-httpd server with its command httpd-stop when I type the C-x C-c command (save-buffers-kill-terminal to quit emacs), cause I would like to get rid of the "Active processes exist; kill them and exit anyway? (yes or no)" message every time I type C-x C-c.
To achieve my aim, I was thinking about writing a hook like:
(add-hook 'save-buffers-kill-terminal
(lambda () (httpd-stop)
))
But it did not work. I continue to get the message "Active processes exist; kill them and exit anyway? (yes or no)" when I type C-x C-c.
How can I achieve my goal?
Thanks!

There is no hook named save-buffers-kill-terminal.
There's a function by that name, but hooks don't automatically exist for every function (the advice mechanism does facilitate that in effect, but you don't need that here (edit: or maybe you do; see below)).
A hook only exists if there is code which explicitly runs it with run-hooks, or similar (e.g. C-u C-h a run.*hook RET). Or more specifically, you can add-hook with any arbitrary variable, but it will never function as a hook unless something runs it.
In general you would use either of kill-emacs-hook (if the callback does not need to interact with the user), or kill-emacs-query-functions if interaction could be necessary. See the help of each of those variables for details.
Edit:
In the case of active processes, a different mechanism is needed, as these queries happen before either of those hooks are run.
If you just want to avoid the query and let the process be killed, you can use set-process-query-on-exit-flag. This sets a per-process flag which determines whether or not this query will happen:
set-process-query-on-exit-flag is a built-in function in `process.c'.
(set-process-query-on-exit-flag PROCESS FLAG)
Specify if query is needed for PROCESS when Emacs is exited.
If the second argument FLAG is non-nil, Emacs will query the user before
exiting or killing a buffer if PROCESS is running. This function
returns FLAG.
You would probably arrange this when you started the process (assuming you have some code which starts httpd), obtaining PROCESS with either (get-process NAME) or (get-buffer-process BUFFER). I'm not using this httpd library, so I don't know specifically what you'll need here.
If you definitely want to call a graceful shut-down function like httpd-stop, I think you'll need to do something custom.
(defadvice save-buffers-kill-emacs (before my-httpd-auto-stop)
(when (httpd-is-running-p) ;; not a real predicate
(httpd-stop)))
(ad-activate 'save-buffers-kill-emacs)
You'll have to figure out what to use in place of my hypothetical httpd-is-running-p, to establish whether or not to call the stop function.
Note that this would run before any other queries, so you might stop httpd this way but then decide not to kill emacs after all (but that sort of thing is possible regardless).
Edit: Alternatively, as it is apparently safe to call this stop function whether or not httpd is running, you could use the following (including an added test to see whether or not httpd-stop is defined, as calling it will be an error otherwise, and I'm not sure how you load the library):
(defadvice save-buffers-kill-emacs (before my-httpd-auto-stop)
(when (fboundp 'httpd-stop)
(httpd-stop)))
(ad-activate 'save-buffers-kill-emacs)

Related

One emacs.d/init.el to suit non-x session and x-session

When I start emacs without an x-server running, some of the things in my init.el fail, eg:
(require 'sr-speedbar)
is inappropriate without a graphical server, where I should rather start
(require 'speedbar)
What do emacs experts recommend as an appropriate init.el configuration in instances where emacs can be called as often from no-x modes as x-based modes? Is there an established way to provide a general, parallel experience under either regime or graceful fallback?
A lot depends on what environments you typically run in and what level of
control you need. For example, if you are just wanting to distinguish between
running under a full graphics capable environment, you can use display-graphic-p
e.g.
(when (display-graphic-p)
;; do stuff which needs a graphic display)
However, if you need to distinguish between different platforms, such as when
running under OSX, you would need something like
(when (eq system-type 'darwin)
;; do stuff which should only run when on OSX'))
Finally, for situations where you need to only configure something when running
under a specific window system, you can use something like
(when (eq window-system 'x)
;; only under X window frame))
However, there are some subtleties to be aware of. Some of these variables, such
as window-system are a test of the current frame. So, you need to think about
when the code is executed. For example, if you run emacs as a daemon, what would
be the value of window-system at the time your init is loaded? Likewise, if you
use emacs as a daemon or use emacsclient to open a new 'frame' it may be opened
a either a graphic or a text frame. Sometimes, you may need to create a new
command which wraps around what you want to do and does the test at the point
you execute the command so that it can respond to the specific frame you are in
when you execute the command.

How to use a minibuffer-exit-hook with read-string

I have not been able to get the minibuffer-exit-hook to play nice with read-string. As far as I can tell, I should no longer be in the minibuffer after finishing up with read-string. However, the condition (minibufferp) says I'm still in the minibuffer even though read-string finished. read-string is written in C, so I can't add the hook there (i.e., at the tail end of the read-string function).
"Documentation [minibuffer-exit-hook]:  Normal hook run just after exit from minibuffer.
[After thinking a little more about this, I'm pretty sure it's a bug -- so I filed a bug report: bug#16524. As I learn more, I'll update this thread.
(defun test ()
(interactive)
(read-string "Prompt: " "testing"))
(add-hook 'minibuffer-exit-hook (lambda ()
(cond
((minibufferp)
(message "Focus is still in the minibuffer: %s" (buffer-name)))
(t (message "Contragulations -- focus is now in: %s." (buffer-name))))))
The doc string is not exact; that's all. The hook is run when inputting text in the minibuffer is done (no longer possible). The buffer that is current when it is run is still the minibuffer. (And that's the way it should be, FWIW.)
Note that the Elisp manual puts it slightly differently (but again, not very precisely):
This is a normal hook that is run whenever the minibuffer is
entered.
("Whenever", meaning about the same time as, not necessarily after.)
If you want to do something after every use of read-string in your code, then define a function that does the following: first (read-string...), then whatever you want done next. And use that function.
If you need to affect also other invocations of read-string, besides those you write in your code, then advise function read-string to perform whatever action after the vanilla code finishes.
For example:
(defadvice read-string (after fooness activate)
(message "buffer: %S" (current-buffer)))
[Note: Yes, you can advise primitives (functions written in C). You used to even be able to advise special forms, but they regressively took away that feature.]
Running a hook after you truly exited the minibuffer is rather pointless: you could be in any kind of buffer (since minibuffer use can be triggered from anywhere) and you hence know very little about the current context (unless you use a buffer-local exit-hook, I guess).
If you want to run a hook when the selected window changes, then your best option is probably to use a post-command-hook that stores the current selected-window in an auxiliary variable and uses it to compare to the previous selected-window.

Emacs process list seems not to work

I am experimenting processes in emacs/ielm for a sort of parallel computing, i.e. to start many processes for different computations and then to wait for all the processes have terminated to compose the result. In order to do this I set up the following simple function:
(defun testp ()
(while (> (length (process-list)) 1)))
I call testp after all the child-processes have been started and, when I get again the control, I compose the result:
If there are no child-processes testp exits immediately: ok;
If there is at least one child-process testp loops: ok;
When all child-processes have finished testp continues looping, and this is
not good.
May I ask you to help me understand where I am wrong.
After a process finishes, it is not necessarily deleted immediately. So (process-list) may still list it. The user variable delete-exited-processes controls this, so check that you have set it to t. The function list-processes will also explicitly delete finished processes, so that may be helpful.
Check out the chapter on processes in the manual for further details.
Emacs is single-threaded and doesn't handle external input (e.g. about the change in a process's status) until it reaches a "safe point". So the above loop (as #juanleon suggests) is "too tight". You want to add a sleep into it.
But better is to use set-process-sentinel so that Emacs gets told when the processes end rather than having to busy-wait for it.
E.g.:
...start a new process stored in proc...
(push proc my-list-of-running-processes)
(set-process-sentinel proc #'my-run-when-its-over)
...
(defun my-run-when-its-over (proc msg)
(setq my-list-of-running-processes (delq proc my-list-of-running-processes))
(unless my-list-of-running-processes
(message "Haha! all my processes are done!")))
Note also that you probably don't want to use process-list since that can contain unrelated processes (e.g. if you use M-x shell or various other things), which is why I used my-list-of-running-processes above.
Maybe the tight loop is not letting emacs do a proper process cleanup. My recommendation would be to apply a filter to the result of (process-list) (since if you have a runnning compilations, server, shell, etc. the process list won't be empty), to filter out processes different of those you are interested in, and also to add a small delay to the while ((sleep 0 500), for instance).

In emacs, running a command before each p4 command

So at work, I've got to work from two different repositories. The files map to essentially the same place, but one path has 'data' in it.
It's relatively trivial to write a defun that determines if the file is in the data directory or not, and so which repository I actually want to check out from. But I can't figure out a way to call my function before any p4 commands without explicitly rebinding the keys to do it, and even that is sort of a big hack. I'd really just like it to run every time I try to check out or revert a file and set the p4port as I want it to.
All the hooks in the p4 system seem to be called when I don't want them to be. I tried calling my defun on the p4-mode-hook, but that hook only runs when the mode is set, and files that aren't in the repository are rejected before I ever get my defun to do anything. :/
There are a couple of approaches that you could use. First, you could consider adding the desired functions to pre-command-hook, with a predicate to check whether the current buffer is operating in p4-mode, i.e.:
(add-hook
'pre-command-hook
(lambda ()
(when (eq major-mode 'p4-mode)
;;; specify whatever functions you desire
)))
This will indiscriminately execute the functions that you include in the body of the above lambda before any command in a p4-mode buffer. If that's overkill and you need to be more selective about when to execute said functions, you should probably individually advise each of the p4 commands that should first execute your functions before running, e.g.:
(defadvice
name-of-p4-function
(before name-of-p4-function-advice activate)
;;; functions to be executed
)
(ad-activate 'name-of-p4-function)
See the Advising functions section of the Emacs manual for additional details.

Is there a direct elisp way to check if a process is running in an emacs term buffer?

I need a check for whether or not a process is still running in my emacs term; started via (term "/bin/bsh") and then renamed to, eg. term-A.
I have tried (term-check-proc "term-A"), but it doesn't show what I what I need, or at least, I don't see how I can use it.
Trying to chase it down by a shell call to ps afx (or the like), is problematic if there is more than one emacs term active and running the same program, (which in my case, is quite quite possible)...
I really need to know if a process in a specific emacs term buffer, term-A, is running or not.
You can get a buffer's process with get-buffer-process:
(get-buffer-process "*shell*") -> #<process shell>
(get-buffer-process "*scratch*") -> nil
After I exit the shell in *shell*, I get nil for that buffer too.