Skip to content

Instantly share code, notes, and snippets.

@jordonbiondo
Created September 30, 2014 20:33
Show Gist options
  • Select an option

  • Save jordonbiondo/67a58aae82b7ab5570a2 to your computer and use it in GitHub Desktop.

Select an option

Save jordonbiondo/67a58aae82b7ab5570a2 to your computer and use it in GitHub Desktop.
background function
(defmacro background-function (&rest args)
"Generates a function that runs in the background.
In order to work in Emacs single threaded environment.
The function must be broken in to steps.
See source for keywords."
(declare (indent defun) (doc-string 3))
(let* ((name (car args))
(margs (cadr args))
(docstring (when (stringp (caddr args))
(concat (caddr args) "\n\n"
"This function will always return nil!")))
(kw (if docstring (cdddr args) (cddr args)))
(using-kw (plist-get kw :using))
(setup-kw (plist-get kw :setup))
(predicate-kw (plist-get kw :continue-if))
(step-kw (plist-get kw :step))
(step-time-kw (or (plist-get kw :step-timeout) 0))
(then-kw (plist-get kw :then)))
`(defun ,name ,margs
,docstring
(let ,using-kw
(let* ((fh (lambda ,(cons 'func margs)
(with-timeout (,step-time-kw (run-with-timer .001 nil func func ,@margs))
(while ,predicate-kw
(progn ,step-kw
(sit-for 0)))
,then-kw)))
(fp (lambda ,(cons 'func margs)
,setup-kw
(with-timeout (,step-time-kw (run-with-timer .001 nil func func ,@margs))
(while ,predicate-kw
(progn ,step-kw
(sit-for 0)))
,then-kw))))
(apply fp fh ,(cons 'list margs))
nil)))))
;; example background function, counting string in file
(background-function string-counter (string file cb)
"Count number of times STRING occurs in FILE, in
a background function, then run CB with the count when finished."
:using ((string-count 0) (pos 0) (buffer (generate-new-buffer "string-counter")))
:setup (with-current-buffer buffer
(delete-region 1 (point-max))
(insert-file-contents file))
:continue-if (with-current-buffer buffer
(goto-char pos)
(ignore-errors (search-forward string)))
:step (with-current-buffer buffer
(incf string-count)
(setq pos (point)))
:step-timeout 0
:then (progn
(kill-buffer buffer)
(apply cb (list string-count))))
;; count the number of "ord"s in the words file in the background
;; then message the number of times found
(string-counter "ord" "/usr/share/dict/words"
(lambda (c) (message "found %d occurences of ord" c)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment