branch: elpa/csv2ledger
commit 8f23cc044fc4bc12b9928a5aca5e9191dae05f42
Author: Joost Kremers <joostkrem...@fastmail.com>
Commit: Joost Kremers <joostkrem...@fastmail.com>

    Use `:set` in c2l-account-matchers-file to set c2l-matchers-regexps.
---
 csv2ledger.el | 106 ++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 58 insertions(+), 48 deletions(-)

diff --git a/csv2ledger.el b/csv2ledger.el
index 3f0296a5f5..eb06558c62 100644
--- a/csv2ledger.el
+++ b/csv2ledger.el
@@ -184,6 +184,54 @@ Ledger entry."
   :type 'function
   :group 'csv2ledger)
 
+(defvar c2l-matcher-regexps nil
+  "Alist of matcher regexps and their acounts.
+Each item should be a cons cell of a regular expression and an
+account name.  If the regular expression matches any of the
+fields in `c2l-target-match-fields', its corresponding account is
+used as the target account.
+
+This variable is normally given a value based on the matchers in
+`c2l-account-matchers-file', but it can also be set directly.")
+
+(defun c2l--read-account-matchers (file)
+  "Read account matchers from FILE.
+See the documentation for the variable
+`c2l-account-matchers-file' for details on the matcher file."
+  (when (stringp file)
+    (if (file-readable-p file)
+        (with-temp-buffer
+          (insert-file-contents file)
+          (goto-char (point-min))
+          (let (accounts)
+            (while (looking-at "\\([[:print:]]+\\)\t\\([[:print:]]+\\)")
+              (let ((matcher (match-string 1))
+                    (account (match-string 2)))
+                (push (cons matcher account) accounts))
+              (forward-line 1))
+            accounts))
+      (user-error "[Csv2Ledger] Account matcher file `%s' not found" file))))
+
+(defun c2l--compile-matcher-regexps (accounts)
+  "Create efficient regular expressions for the matchers in ACCOUNTS.
+ACCOUNTS is a list of (<matcher> . <account>) conses, where
+<matcher> should be unique but <account> may occur multiple
+times.  Return value is an alist in which each account in
+ACCOUNTS is mapped to a regular expression matching all matchers
+for that account."
+  (mapcar (lambda (e)
+            (cons (regexp-opt (mapcar #'car (cdr e)))
+                  (car e)))
+          (seq-group-by #'cdr accounts)))
+
+(defun c2l-set-matcher-regexps (val)
+  "Set `c2l-matcher-regexps' based on VAL, unless it already has a value."
+  (unless c2l-matcher-regexps
+    (setq c2l-matcher-regexps
+          (-> val
+              (c2l--read-account-matchers)
+              (c2l--compile-matcher-regexps)))))
+
 (defcustom c2l-account-matchers-file nil
   "File containing matcher strings mapped to accounts.
 This should be a TSV (tab-separated values) file containing one
@@ -198,20 +246,17 @@ where the two columns are separated by a TAB.
 The matcher is a string (not a regular expression).  If a matcher
 is found in any of the fields listed in the option
 `c2l-target-match-fields', the corresponding account is used to
-book the transaction."
-  :type 'file
-  :group 'csv2ledger)
+book the transaction.
 
-(defvar c2l-matcher-regexps nil
-  "Alist of matcher regexps and their acounts.
-Each item should be a cons cell of a regular expression and an
-account name.  If the regular expression matches any of the
-fields in `c2l-target-match-fields', its corresponding account is
-used as the target account.
-
-This variable is normally given a value based on the matchers in
-`c2l-account-matchers-file', but you can also set in directly if
-you prefer to use regexps to match accounts.")
+Note that the variable `c2l-matcher-regexps' is set based on the
+value of this option.  Therefore, if you set this option outside
+of Customize, make sure to also call the function
+`c2l-set-matcher-regexps'."
+  :type 'file
+  :group 'csv2ledger
+  :set (lambda (sym val)
+         (set sym val)
+         (c2l-set-matcher-regexps val)))
 
 (defcustom c2l-target-match-fields '(payee description)
   "List of fields used for determining the target account.
@@ -339,43 +384,8 @@ cleared, even if there is no value for `posted' in 
TRANSACTION."
             accounts))
       (user-error "[Csv2Ledger] Accounts file `%s' not found" file))))
 
-(defun c2l--read-account-matchers (file)
-  "Read account matchers from FILE.
-See the documentation for the variable
-`c2l-account-matchers-file' for details on the matcher file."
-  (when (stringp file)
-    (if (file-readable-p file)
-        (with-temp-buffer
-          (insert-file-contents file)
-          (goto-char (point-min))
-          (let (accounts)
-            (while (looking-at "\\([[:print:]]+\\)\t\\([[:print:]]+\\)")
-              (let ((matcher (match-string 1))
-                    (account (match-string 2)))
-                (push (cons matcher account) accounts))
-              (forward-line 1))
-            accounts))
-      (user-error "[Csv2Ledger] Account matcher file `%s' not found" file))))
-
-(defun c2l--compile-matcher-regexps (accounts)
-  "Create efficient regular expressions for the matchers in ACCOUNTS.
-ACCOUNTS is a list of (<matcher> . <account>) conses, where
-<matcher> should be unique but <account> may occur multiple
-times.  Return value is an alist in which each account in
-ACCOUNTS is mapped to a regular expression matching all matchers
-for that account."
-  (mapcar (lambda (e)
-            (cons (regexp-opt (mapcar #'car (cdr e)))
-                  (car e)))
-          (seq-group-by #'cdr accounts)))
-
 (defun c2l--match-account (str)
   "Try to match STR to an account."
-  (unless c2l-matcher-regexps
-    (setq c2l-matcher-regexps
-          (-> c2l-account-matchers-file
-              (c2l--read-account-matchers)
-              (c2l--compile-matcher-regexps))))
   (--some (if (string-match-p (car it) str)
               (cdr it))
           c2l-matcher-regexps))

Reply via email to