help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Making sure I'm not checking email (or doing other things) too often


From: Michael Heerdegen
Subject: Re: Making sure I'm not checking email (or doing other things) too often
Date: Mon, 15 Feb 2016 15:40:34 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.91 (gnu/linux)

Marcin Borkowski <mbork@mbork.pl> writes:

> (defun not-too-often-add-guard (fun interval)
>   "Add a not-too-often guard to FUN with INTERVAL.
> This means that if FUN gets called less than INTERVAL minutes
> after last call, the use is asked whether s?he really wants to
> run the command."
>   (let* ((fun-name (symbol-name fun))
>        (nto-int-sym
>         (intern (concat "not-too-often-interval-" fun-name)))
>        (nto-last-time-sym
>         (intern (concat "not-too-often-last-time-" fun-name)))
>        (nto-guard-sym
>         (intern (concat "not-too-often-guard-" fun-name))))
>     (set nto-int-sym interval)
>     (set nto-last-time-sym 0)
>     (fset nto-guard-sym (lambda (orig-fun &rest args)
>                         (let ((elapsed (time-to-seconds
>                                         (time-subtract
>                                          (current-time)
>                                          (symbol-value nto-last-time-sym)))))
>                           (if (< elapsed
>                                  (* 60 (symbol-value nto-int-sym)))
>                               (cond ((y-or-n-p
>                                       (format "You called %s %s minutes ago.  
> Are you sure you want to proceed? "
>                                               fun-name (/ elapsed 60.0)))
>                                      (set nto-last-time-sym (current-time))
>                                      (apply orig-fun args))
>                                     (t
>                                      (keyboard-quit)))
>                             (set nto-last-time-sym (current-time))))))
>     (put nto-guard-sym 'function-documentation
>        (format
>         "Issue a warning if function `%s' is called less than %s minutes from 
> last call."
>         fun-name interval))
>     (advice-add fun :around nto-guard-sym)))
>
> Now I can say e.g.
>
> (not-too-often-add-guard 'mu4e-update-mail-and-index 15)
>
> and have Emacs warn me if I want to check for new email sooner than 15
> minutes after last time.
>
> Opinions welcome.

That looks very good!

[ An alternative approach would be to make `not-too-often-add-guard' a
macro.  This would avoid the need of using `symbol-value' which some
find not aesthetic, but that's more a matter of personal taste, and you
surely know that already. ]

FWIW, the functionality "let a command behave differently depending on
how much time since its last invocation has elapsed" is useful in other
contexts too.  E.g. when you want to make a key to behave differently
when you hit it multiple times in fast succession.

Factoring out the greatest common divider would give you something like
this:

--8<---------------cut here---------------start------------->8---
-*- lexical-binding: t -*-

(defun stopwatch ()
  "Return a fresh stopwatch.
This is a function accepting zero arguments that upon each call
will return the time difference from its last call in seconds.
When called the first time it will return nil."
  (let ((last-invocation nil))
    (lambda ()
      (prog1 (and last-invocation
                   (time-to-seconds (time-subtract (current-time) 
last-invocation)))
         (setq last-invocation (current-time))))))
--8<---------------cut-here---------------end--------------->8---

With that, one could make your advice functions reference and use such a
stopwatch object (each an individual one, of course).


Regards,

Michael.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]