From 7d461a7d4f62d357a224741b9e808f1abada8d15 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Sun, 2 Nov 2014 11:52:08 -0500 Subject: Introduce persistent storage for filters --- stack-filter.el | 39 +++++++++++++++++++++++++++++++++++++++ test/tests.el | 19 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/stack-filter.el b/stack-filter.el index 0229ad1..e5fb54d 100644 --- a/stack-filter.el +++ b/stack-filter.el @@ -32,6 +32,9 @@ ;;; Customizations +(defconst stack-filter-cache-file + "filters.el") + (defvar stack-filter 'default "The current filter. @@ -66,6 +69,42 @@ or string." (cdr (assoc 'filter (elt response 0))))))) + +;;; Storage and Retrieval + +(defun stack-filter-get (filter) + "Retrieve named FILTER from `stack-filter-cache-file'." + (with-current-buffer (stack-cache-get-file stack-filter-cache-file) + (or (cdr (ignore-errors (assoc filter (read (buffer-string))))) + nil))) + +(defun stack-filter-store (name filter) + "Store NAME as FILTER in `stack-filter-cache-file'. + +NAME should be a symbol and FILTER is a string as compiled by +`stack-filter-compile'." + (unless (symbolp name) + (error "Name must be a symbol: %S" name)) + (with-current-buffer (stack-cache-get-file stack-filter-cache-file) + (let* ((dict (or (ignore-errors + (read (buffer-string))) + nil)) + (entry (assoc name dict))) + (if entry (setf (cdr entry) filter) + (setq dict (cons (cons name filter) dict))) + (erase-buffer) + (insert (prin1-to-string dict)) + (save-buffer) + dict))) + +;;; TODO tail recursion should be made more efficient for the +;;; byte-compiler +(defun stack-filter-store-all (name-filter-alist) + (when name-filter-alist + (stack-filter-store + (caar name-filter-alist) + (cdar name-filter-alist)) + (stack-filter-store-all (cdr name-filter-alist)))) (provide 'stack-filter) ;;; stack-filter.el ends here diff --git a/test/tests.el b/test/tests.el index 44b0de0..fa60364 100644 --- a/test/tests.el +++ b/test/tests.el @@ -75,3 +75,22 @@ ((should-not-go)) ((1 . alpha) (2 . beta))] '(1 2 3))))) + +(ert-deftest test-filters () + ;; Ensure the file is empty + (ignore-errors + (delete-file + (stack-cache-get-file-name + stack-filter-cache-file))) + + (should-error (stack-filter-store "names must be symbols" + "this is a filter")) + ;; basic use + (should (equal '((test . "filter")) + (stack-filter-store 'test "filter"))) + ;; aggregation + (should (equal '((test2 . "filter2") (test . "filter")) + (stack-filter-store 'test2 "filter2"))) + ;; mutation + (should (equal '((test2 . "filter2") (test . "filter-test")) + (stack-filter-store 'test "filter-test")))) -- cgit v1.2.3