summaryrefslogtreecommitdiff
path: root/README.org
blob: 0b30f5e780d58cbfa7a14a13c42e776a3b005145 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
* Timeout: Sometimes Emacs needs one

------

*Breaking Change*: This library is being upstreamed into Emacs.  For consistency with Elisp naming guidelines, the names of the functions have been changed, and the version has been bumped to v2.0.  Sorry about that.

The naming changes are:
#+begin_src emacs-lisp
timeout-throttle  -> timeout-throttled-func
timeout-throttle  -> timeout-throttled-func
timeout-throttle! -> timeout-throttle
timeout-throttle! -> timeout-throttle
#+end_src

------

=timeout= is a small library to help you throttle or debounce elisp function calls.  See [[https://karthinks.com/software/cool-your-heels-emacs][this write-up]] for an introduction and potential uses.

It's actually tiny, just a couple of functions.

*** To use this library:

You can throttle an elisp function =func= to run at most once every 2 seconds:
#+begin_src emacs-lisp
(timeout-throttle 'func 2.0)
#+end_src

To reset =func=:
#+begin_src emacs-lisp
(timeout-throttle 'func 0.0)
#+end_src

When the call is a noop, a throttled function will return the same result as the last successful run.

You can debounce an elisp function =func= to run after an uninterrupted delay of 0.5 seconds:
#+begin_src emacs-lisp
(timeout-debounce 'func 0.5)
#+end_src

To reset =func=:
#+begin_src emacs-lisp
(timeout-debounce 'func 0.0)
#+end_src

By default a debounced function returns =nil= at call time.  To change this, run:
#+begin_src emacs-lisp
(timeout-debounce 'func 0.5 'some-return-value)
#+end_src

Instead of advising =func=, you can also create new throttled or debounced versions of it with =timeout-throttle= and =timeout-debounce=:

#+begin_src emacs-lisp
(timeout-throttled-func 'func 2.0)
(timeout-debounced-func 'func 0.5)
#+end_src

These return anonymous functions which you can bind to a symbol with =defalias= or =fset=:
#+begin_src emacs-lisp
(defalias 'throttled-func (timeout-throttled-func 'func 2.0))
(fset     'throttled-func (timeout-throttled-func 'func 2.0))
#+end_src

*** Dynamic duration

All timeout functions support dynamic duration by passing a symbol or function instead of a number:

#+begin_src emacs-lisp
;; Using a variable for dynamic timeout
(defvar my-timeout 1.5)
(timeout-throttle 'func 'my-timeout)  ; uses value of my-timeout

;; Using a function for conditional behavior
(timeout-throttle 'func (lambda () (if busy-p 0.1 2.0)))

;; The duration is evaluated at runtime, so you can change it dynamically
(setq my-timeout 3.0)  ; throttle duration is now 3 seconds
#+end_src

When passed a symbol, its value is used as the duration. When passed a function, it is called with no arguments to get the duration. This allows for adaptive timeouts based on system state or user preferences.