From 01307c43d70949b8bba63eaf3ddfd8a712e78875 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Sun, 2 Nov 2014 10:39:07 -0500 Subject: Whitespace normalization in stack-filter.el --- stack-filter.el | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'stack-filter.el') diff --git a/stack-filter.el b/stack-filter.el index 1525a4b..75173a1 100644 --- a/stack-filter.el +++ b/stack-filter.el @@ -51,19 +51,20 @@ excluding those from EXCLUDE, using BASE as a base filter. INCLUDE and EXCLUDE must both be lists; BASE should be a symbol or string." (let ((keyword-arguments - `((include . ,(if include (mapconcat - #'stack-core-thing-as-string - include ";"))) - (exclude . ,(if exclude (mapconcat - #'stack-core-thing-as-string - exclude ";"))) - (base . ,(if base base))))) + `((include . ,(if include (mapconcat + #'stack-core-thing-as-string + include ";"))) + (exclude . ,(if exclude (mapconcat + #'stack-core-thing-as-string + exclude ";"))) + (base . ,(if base base))))) (let ((response (stack-core-make-request - "filter/create" - keyword-arguments))) + "filter/create" + keyword-arguments))) (url-hexify-string (cdr (assoc 'filter - (elt response 0))))))) + (elt response 0))))))) + (provide 'stack-filter) ;;; stack-filter.el ends here -- cgit v1.2.3 From d2a8e8e9c146c0cce084f7b4e6371a882374435e Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Sun, 2 Nov 2014 11:51:39 -0500 Subject: Checkdoc file --- stack-filter.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'stack-filter.el') diff --git a/stack-filter.el b/stack-filter.el index 75173a1..0229ad1 100644 --- a/stack-filter.el +++ b/stack-filter.el @@ -34,7 +34,8 @@ (defvar stack-filter 'default - "The current filter. To customize the filter for the next call + "The current filter. +To customize the filter for the next call to `stack-core-make-request', let-bind this variable to the output of a call to `stack-core-compile-filter'. Be careful! If you're going to be using this new filter a lot, create a variable @@ -42,11 +43,11 @@ for it. Creation requests count against `stack-core-remaining-api-requests'!") -;;; Filter compilation +;;; Compilation +;;; TODO allow BASE to be a precompiled filter name (defun stack-filter-compile (&optional include exclude base) - "Compile a StackExchange filter including fields from INCLUDE, -excluding those from EXCLUDE, using BASE as a base filter. + "Compile INCLUDE and EXCLUDE into a filter derived from BASE. INCLUDE and EXCLUDE must both be lists; BASE should be a symbol or string." -- cgit v1.2.3 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(+) (limited to 'stack-filter.el') 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 From f349fe5d764730a0a339045a59a46d53b9a33100 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Sun, 2 Nov 2014 13:11:15 -0500 Subject: Implement and use `stack-cache-get' and `-set' --- stack-core.el | 30 +++++++++++++++++++++++------- stack-filter.el | 24 +++++++++--------------- 2 files changed, 32 insertions(+), 22 deletions(-) (limited to 'stack-filter.el') diff --git a/stack-core.el b/stack-core.el index f9b9669..c2aff15 100644 --- a/stack-core.el +++ b/stack-core.el @@ -249,13 +249,29 @@ entire response as a complex alist." "Expands FILENAME in the context of `stack-cache-directory'." (expand-file-name filename stack-cache-directory)) -(defun stack-cache-get-file (filename) - "Return a buffer for FILENAME from `stack-cache-directory'." - (let ((find-file-hook nil) - (file (stack-cache-get-file-name filename))) - (unless (file-exists-p stack-cache-directory) - (mkdir stack-cache-directory)) - (find-file-noselect file))) +(defun stack-cache-get (cache) + "Return the data within CACHE. + +As with `stack-cache-set', CACHE is a file name within the +context of `stack-cache-directory'." + (unless (file-exists-p stack-cache-directory) + (mkdir stack-cache-directory)) + (let ((file (stack-cache-get-file-name cache))) + (when (file-exists-p file) + (with-temp-buffer + (insert-file-contents (stack-cache-get-file-name cache)) + (read (buffer-string)))))) + +(defun stack-cache-set (cache data) + "Set the content of CACHE to DATA. + +As with `stack-cache-get', CACHE is a file name within the +context of `stack-cache-directory'." + (unless (file-exists-p stack-cache-directory) + (mkdir stack-cache-directory)) + (write-region (prin1-to-string data) nil + (stack-cache-get-file-name cache)) + data) (provide 'stack-core) ;;; stack-core.el ends here diff --git a/stack-filter.el b/stack-filter.el index e5fb54d..91c4875 100644 --- a/stack-filter.el +++ b/stack-filter.el @@ -74,9 +74,7 @@ or string." (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))) + (cdr (assoc filter (stack-cache-get stack-filter-cache-file)))) (defun stack-filter-store (name filter) "Store NAME as FILTER in `stack-filter-cache-file'. @@ -85,17 +83,12 @@ 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))) + (let* ((dict (stack-cache-get stack-filter-cache-file)) + (entry (assoc name dict))) + (if entry (setcdr entry filter) + (setq dict (cons (cons name filter) dict))) + + (stack-cache-set stack-filter-cache-file dict))) ;;; TODO tail recursion should be made more efficient for the ;;; byte-compiler @@ -104,7 +97,8 @@ NAME should be a symbol and FILTER is a string as compiled by (stack-filter-store (caar name-filter-alist) (cdar name-filter-alist)) - (stack-filter-store-all (cdr name-filter-alist)))) + (stack-filter-store-all + (cdr name-filter-alist)))) (provide 'stack-filter) ;;; stack-filter.el ends here -- cgit v1.2.3 From e089914f96caf5e1a74acb75995634c34455a290 Mon Sep 17 00:00:00 2001 From: Sean Allred Date: Sun, 2 Nov 2014 13:40:46 -0500 Subject: Simplify filter-store-all by modifying *-store --- stack-filter.el | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'stack-filter.el') diff --git a/stack-filter.el b/stack-filter.el index 91c4875..4210549 100644 --- a/stack-filter.el +++ b/stack-filter.el @@ -76,29 +76,28 @@ or string." "Retrieve named FILTER from `stack-filter-cache-file'." (cdr (assoc filter (stack-cache-get stack-filter-cache-file)))) -(defun stack-filter-store (name filter) +(defun stack-filter-store (name &optional 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)) - (let* ((dict (stack-cache-get stack-filter-cache-file)) - (entry (assoc name dict))) - (if entry (setcdr entry filter) - (setq dict (cons (cons name filter) dict))) - - (stack-cache-set stack-filter-cache-file dict))) - -;;; TODO tail recursion should be made more efficient for the -;;; byte-compiler +`stack-filter-compile'. + +If NAME is a cons cell, (car NAME) is taken to be the actual NAME +and (cdr NAME) is taken to be the actual FILTER. In this case, +the second argument is simply ignored." + (let ((name (if (consp name) (car name) name)) + (filter (if (consp name) (cdr name) filter))) + (unless (symbolp name) + (error "Name must be a symbol: %S" name)) + (let* ((dict (stack-cache-get stack-filter-cache-file)) + (entry (assoc name dict))) + (if entry (setcdr entry filter) + (setq dict (cons (cons name filter) dict))) + + (stack-cache-set stack-filter-cache-file dict)))) + (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)))) + (mapc #'stack-filter-store name-filter-alist)) (provide 'stack-filter) ;;; stack-filter.el ends here -- cgit v1.2.3