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).
Related
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.
I'm trying to write an emacs function that executes a shell command every 5 seconds. However, I can't get the pause to work. Here's what I have:
(while '(test)
(insert (format "echo hello"))
(comint-send-input))
(sleep-for 0 5000)
I suspect that the sleep is ignored for reasons related to functional evaluation of Lisp. Any advice on how to get the pause to occur after each command evaluation?
As mentioned in the comment, the issue is with a paren.
Also, I've just tried sit-for in *scratch* and it performs smoother compared to sleep-for.
(while 1
(insert "hello")
(sit-for 1))
But both lock up Emacs, since it's single threaded, so you should be careful with this sort of activity.
Consider using async package or something similar instead.
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)
What problem can happen if the goto-line function is used in a non-interactive elisp program? Its docstring gives a warning saying that:
This function is usually the wrong thing to use in a Lisp program.
What you probably want instead is something like:
(goto-char (point-min)) (forward-line (1- N))
Moreover, when I try to byte-compile-file my init file including goto-line, I get a unpleasant warning like this once again:
.emacs:170:19:Warning: `goto-line' used from Lisp code
That command is designed for interactive use only
Is using goto-line in a non-interactive program really so dangerous? Relatedly, why is the suggested forward-line solution preferable?
Firstly, this prevents Elisp programmers from fall into bad habits -- writing
inefficient code in a line-number centric way. i.e. instead of using
(forward-line 1) calculating the current line number, incrementing, and using
goto-line.
From this mailing list article:
In a nutshell, the reason why goto-line should not be a frequently
used command is that normally there's no reason to want to get to line
number N unless you have a program that told you there's something
interesting on that line.
Secondly, goto-line manipulates the user's environment in addition to moving
the point (i.e. push-mark). For non-interactive use, this may not be what
you want. On the other hand if having considered all this, you believe
goto-line is exactly what you need, then just call it like this:
(defun foo ()
(interactive)
(with-no-warnings
(goto-line N)))
And you won't get any compiler warnings.
in addition to what was said:
"goto-line" finally recurs onto "(forward-line (1- line)", which in effect does the work. All other of the 43 lines of "goto-line" command body deal with interactive use. For example considering a possibly universal argument.
When writing a program resp. when running it, your computer is in another state than following an interactive call. Thus you should address this state by using "forward-line" straight on.
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.