0

I understand in general about idle timers in emacs, but I'm having trouble figuring out how to do the following ...

I want to set an is-idle variable to t when emacs is in an idle state, and I want that variable to set to nil when emacs is not idle.

Why do I want this? It's because I have written signal handlers for sigusr1 and sigusr2 which get invoked when my emacs process receives either of these external signals. I want the handlers not to run if emacs doesn't happen to be idle at the moment that the sigusr1 or sigusr2 signals are received.

In other words, I want my signal handler to look like this:

(when is-idle
   ;; do all the sigusr1/sigusr2 processing
   ;; ... etc. ...
   )

I haven't figured out how to manage this with an idle timer, nor with any other emacs facilities.

Instead of a variable, is-idle could be a function. I don't really care which it is. I just want to know at the moment that the signal is received as to whether my emacs session is idle or not.

Thanks in advance.

Update ...

I came across the (current-idle-time) function. Here's its doc string ...

Return the current length of Emacs idleness, or nil.
The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC)
in the same style as (current-time).

The value when Emacs is not idle is nil.

PSEC is a multiple of the system clock resolution.

I'm going to do some investigation as to whether this function will provide what I'm looking for, and I'll report back.

5
  • I presume you've attempted to make your signal handlers schedule their work with an idle timer, and that hasn't worked for some reason? If I've read the question correctly, that sounds like what you want to do, so show us the code you tried to use for that... – phils Apr 10 '17 at 0:26
  • Thank you. I already understand how to do that. However, I actually want the opposite to take place. I want the signal handler to do its work either (1) exactly at the moment that the signal is delivered, or (2) not at all, if emacs is not idle. I don't know if this is even possible under emacs. – HippoMan Apr 10 '17 at 1:05
  • The current-idle-time function might do what I want. See the update I added to my original message. – HippoMan Apr 10 '17 at 3:29
  • i.e. the answer I posted 3 hours ago? :) – phils Apr 10 '17 at 4:23
  • Sorry, I didn't do a "refresh" of my web page before posting my own answer, so I didn't see yours. – HippoMan Apr 10 '17 at 16:47
0

C-hf current-idle-time

current-idle-time is a built-in function in ‘C source code’.

(current-idle-time)

Return the current length of Emacs idleness, or nil.
The value when Emacs is idle is a list of four integers (HIGH LOW USEC PSEC)
in the same style as (current-time).

The value when Emacs is not idle is nil.

PSEC is a multiple of the system clock resolution.
4
  • Yes, this is the function I was looking for ... sort of. However, it seems to return nil, even when emacs has been idle for a very long time. I believe that it only returns a meaningful value within the context of an idle handler. I'm investigating further. – HippoMan Apr 10 '17 at 16:53
  • I can run a normal timer which displays expected idle-time results. Assuming you're testing with your signal handler, maybe signal handling makes Emacs non-idle. (If that's not how you're testing, what are you doing? Obviously user interaction of any kind makes Emacs non-idle, so you'll always get nil if you invoke the function directly). – phils Apr 10 '17 at 22:16
  • Yes, if I have a timer displaying increasing idleness, and I send SIGUSR1, Emacs ceases to be idle. – phils Apr 10 '17 at 22:23
  • That behavior makes sense. My answer (below) takes this into account, and it solves my problem. – HippoMan Apr 11 '17 at 2:44
0

Even though (current-idle-time) only seems to return a meaningful value within the context of an idle handler, I figured out how to use it for my purpose ...

;; Initialize to idle mode upon emacs startup.
(defvar my-last-idle t
  "*Last idle time value.")

(defun my-pre-command-hook ()
  (setq my-last-idle nil))

(defun my-idle-timer-hook ()
  (setq my-last-idle (current-idle-time)))

(add-hook 'pre-command-hook 'my-pre-command-hook)
(run-with-idle-timer 1 t 'my-idle-timer-hook)

Then, my sigusr1/sigusr2 handler can do this ...

(when my-last-idle
  ;; Do my signal-handling stuff.
  ;; ... etc. ...
  )

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.