Is there any way to write something like this without taking over emacs?
(defun dumb-wait (seconds)
(let ((done (+ (second (current-time)) seconds)))
(while (< (second (current-time)) done)
(message "waiting"))))
(dump-wait 5) will block emacs from 5 seconds. Is there anyway to write this so it doesn't block? I just want to be in a loop and check some condition from time to time, and still be able to use emacs.
Thanks!
(run-at-time time repeat function &rest args) should do it. nil as time means now.
(setq my-timer
(run-at-time nil 5 (lambda () (message "waiting")))) ; returns timer object
;; or
(setq my-timer
(run-at-time nil 5 'message "waiting"))
(cancel-timer my-timer) ; use timer object from above
Edit:
The parameter repeat expects a number as seconds, however there's a function timer-duration, which you can use instead of the number. It returns the number of seconds as provided with a string parameter. This is somewhat easier to read for big intervals.
(timer-duration "3 hours 2 seconds 1 millisec") ; => 10802.001
Possible word you can use are defined in the variable timer-duration-words.
On a related note, there's no general way to write Emacs Lisp code that doesn't block because the language doesn't have features like coroutines, continuations and threading (yet). Instead, you've got to look for asynchronous inbuilts that do something closest to what you want. Example: url-retrieve and async-shell-command. Some applications like SLIME have managed to work around this issue and have implemented a sort of threading on their own, while others like gnus are waiting for Emacs Lisp to improve.
Related
In my .emacs file, I have:
(defadvice narrow-to-region (around test activate)
(message "advice")
ad-do-it)
When I call narrow-to-region, the advice runs and prints 'advice' before narrowing.
When I call narrow-to-defun, it does not.
I found where narrow-to-defun is defined - in lisp.el, and re-evaluated the function. At this point, the advice started running.
What could cause this?
The problem is, apparently, due to byte-compilation and therefore the inability to advise the narrowing primitives (narrow-to-region is the primitive, narrow-to-defun calls narrow-to-region).
The following post on Null Program ("The Limits of Emacs Advice") goes into detail about this problem. Here's the shortish version from deep in the post:
It turns out narrow-to-region is so special -- probably because it's used very frequently -- that it gets its own bytecode. The primitive function call is being compiled away into a single instruction. This means my advice will not be considered in byte-compiled code. Darnit. The same is true for widen (code 126).
As to why the advice started working after you re-evaluated narrow-to-defun: I'm guessing it's because you ended up replacing the byte-compiled version when you re-evaluated.
#Dan described the problem well. Here is some info that might help you work around it.
What you can do is to advise (or to redefine) also narrow-to-defun (and perhaps narrow-to-page), so it acts similarly.
FWIW, I do something similar in library wide-n.el (see Multiple Narrowings).
I advise narrow-to-region. But I also redefine narrow-to-defun and narrow-to-page. In all 3 cases I make the same change, to record the details of each narrowing so you can return to them later. Here is the advice, for example:
(defadvice narrow-to-region (before push-wide-n-restrictions activate)
"Push the region limits to `wide-n-restrictions'.
You can use `C-x n x...' to widen to previous buffer restrictions."
(when (or (interactive-p) wide-n-push-anyway-p)
(wide-n-push (ad-get-arg 0) (ad-get-arg 1)))) ; Args START and END.
And here is the relevant part of the narrow-to-defun redefinition:
...
(goto-char end)
(re-search-backward "^\n" (- (point) 1) t)
(when (or (interactive-p) wide-n-push-anyway-p) (wide-n-push beg end)) ; <=====
(narrow-to-region beg end))))
I'm looking for some assistance, please, to measure the time of a function call when using a while loop -- i.e., the clock should stop when the function throws done. I found the following timer on the mailing list: http://lists.gnu.org/archive/html/help-gnu-emacs/2008-06/msg00087.html
(defmacro measure-time (&rest body)
"Measure the time it takes to evaluate BODY."
`(let ((time (current-time)))
,#body
(message "%.06f" (float-time (time-since time)))))
It's used like this:
(measure-time
(dotimes (i 100000)
(1+ 1)))
An example of how to use the timer macro with a while loop would be greatly appreciated. I'm looking for the total time beginning from before the while loop commenced to the end when done is thrown.
(defun test ()
(measure-time)
(catch 'done
(while t
[*** do a bunch of stuff]
(when (condition-satisfied-p)
[*** STOP THE CLOCK AND PRINT TOTAL DURATION ***]
(throw 'done nil) ))))
Exactly as per the example you've quoted. You literally wrap (measure-time ... ) around the thing you're timing. The entirety of the catch expression, in your case.
Did you not try that?
BTW, this macro is called benchmark-elapse in Emacs, but it is not autoloaded, so you need to (require 'benchmark) before using it.
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 have emacs + sbcl + slime installed. I have this function defined
(defun jugar ()
(let* ((nodoActual *nodo-inicial*)
(estadoActual (nodo-estado nodoActual))
(timeStart nil)
(timeEnd nil)
)
(loop while (not (es-estado-final estadoActual)) do
(setf *hojas* 0)
(setf timeStart (get-universal-time))
(setf nodoActual (decision-minimax nodoActual *profundidad* timeStart))
(setf timeEnd (get-universal-time))
(setf estadoActual (nodo-estado nodoActual))
(imprime-en-fichero estadoActual)
(format t "Hojas analizadas: ~a ~%" *hojas*)
(format t "Tiempo empleado: ~a ~%~%" time))
))
that makes a series of calls and print some variables in a loop.
The problem is when I call (jugar) from the *slime-repl sbcl* buffer, the prompt waits until (jugar) execution ends for showing all the (format …) together. I tried the same from a terminal (running sbcl) and it works well, so I guess it is something related to emacs or slime. How can I fix it?
proksid's answer mentions force-output, which is on the right track, but there are actually a few related possibilities. The documentation for force-output also describes finish-output (and clear-output, which isn't relevant for us):
finish-output, force-output, and clear-output exercise control over
the internal handling of buffered stream output.
finish-output attempts to ensure that any buffered output sent to
output-stream has reached its destination, and then returns.
force-output initiates the emptying of any internal buffers but does
not wait for completion or acknowledgment to return.
clear-output attempts to abort any outstanding output operation in
progress in order to allow as little output as possible to continue to
the destination.
If you want to guarantee that the output from the different iterations doesn't get interleaved (I don't know whether this is likely or not), you might want to consider finish-output instead of force-output. In either case, at least be aware of both options.
Add (force-output) after last (format ) call.
I have added a lambda() function to run-with-idle-timer like this:
(run-with-idle-timer my-configurable-idle-time t
(lambda ()
;;; do something
) )
Is it possible to remove this function at a later point again from the idle timer trigger?
Yes, run-with-idle-timer returns a timer object which you can pass to cancel-timer.
If you did not keep the timer object around, you can modify timer-idle-list by hand.
See also Getting a list of running Emacs timers.
I also came across a similar situation, where I wanted to kill a timer I started with:
(setq my-timer (run-with-timer 5 5 'my-func))
However,
(cancel-timer my-timer)
was not working because it said my-timer was not set (don't know why this was happening).
In addition to the method of the first poster, it can be killed with:
(cancel-function-timers 'my-func)
This cancels all the timers calling function 'my-func.
To kill it by altering timer-list, which I also tested, I did the following:
(length timer-list) ;; I had two timers..one good, one bad
(cdr timer-list) ;; I verified the last was the one I wanted to keep
(setq timer-list (cdr timer-list)) ;; I reset timer-list
Obviously, this list structure will vary, so you'll have to adjust accordingly. Substitute "timer-idle-list" if you started your timer with (run-with-idle-timer)
This should also work if you started your timer with 'gamegrid-start-timer and 'gamegrid-kill-timer is not working, since 'gamegrid-start-timer is essentially just a wrapper for 'run-with-timer
One more solution: if you're out of luck and can't actually cancel the timer, you can always use
(defvar my-timer-enabler t)
(run-with-idle-timer my-configurable-idle-time t
(lambda ()
(when my-timer-enabler
;;; do something
)))
So you can disable the timer by setting my-timer-enabler to nil. And you can later re-enable the timer by simply setting the var back to t.