Created
September 30, 2014 20:33
-
-
Save jordonbiondo/67a58aae82b7ab5570a2 to your computer and use it in GitHub Desktop.
background function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (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