[nongnu] elpa/cider d430ab314f: [complete] Prioritize flex style if flex style is requested
branch: elpa/cider commit d430ab314f7f59cf88e19fe4629bb46a1108ddbb Author: Oleksandr Yakushev Commit: Bozhidar Batsov [complete] Prioritize flex style if flex style is requested --- CHANGELOG.md | 2 ++ cider-completion.el| 2 +- test/cider-completion-tests.el | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acce10fb35..54ef88a462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs fixed +- [#3696](https://github.com/clojure-emacs/cider/pull/3696): Don't eagerly complete a candidate if there are other candidates matching `flex` style. + ## 1.14.0 (2024-05-30) ### New features diff --git a/cider-completion.el b/cider-completion.el index bd23c38593..a2a91ae57d 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -297,7 +297,7 @@ Only affects the `cider' completion category.`" (unless found-styles (setq found-styles '(styles basic))) (unless (member 'flex found-styles) - (setq found-styles (append found-styles '(flex + (setq found-styles (apply #'list 'styles 'flex (cdr found-styles (add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle (list found-cycle)) diff --git a/test/cider-completion-tests.el b/test/cider-completion-tests.el index e80f4253ae..a8f58f798b 100644 --- a/test/cider-completion-tests.el +++ b/test/cider-completion-tests.el @@ -37,7 +37,7 @@ (unwind-protect (progn (it "adds `flex' and `basic' as a fallback" - (let ((expected-category-overrides '((cider (styles basic flex) + (let ((expected-category-overrides '((cider (styles flex basic) (cider-enable-flex-completion) (expect (member 'flex (assq 'styles (assq 'cider completion-category-overrides))) :to-be-truthy)
[nongnu] elpa/editorconfig cd61ca47e3: Update CHANGELOG.md (#339)
branch: elpa/editorconfig commit cd61ca47e3013e59ebfa4cd5e04e1878c9a725db Author: 10sr <8.slas...@gmail.com> Commit: GitHub Update CHANGELOG.md (#339) * Update CHANGELOG.md * Update CHANGELOG.md --- CHANGELOG.md | 13 + 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08cd608de8..7c34f20a89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Support new major-modes + - svelte-mode ([#333]) + - magik-mode, magik-ts-mode ([#336]) +- Add switch not to override local variable values ([#338]) + - Set `editorconfig-override-file-local-variables` to nil to use file local +variable values instead of values in .editorconfig + - Set `editorconfig-override-dir-local-variables` to nil to use values defined in +.dir-locals.el instead of values in .editorconfig + + ### Changed ### Deprecated @@ -335,6 +345,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [0.3]: https://github.com/editorconfig/editorconfig-emacs/compare/v0.2...v0.3 [0.2]: https://github.com/editorconfig/editorconfig-emacs/compare/v0.1...v0.2 [0.1]: https://github.com/editorconfig/editorconfig-emacs/releases/tag/v0.1 +[#338]: https://github.com/editorconfig/editorconfig-emacs/issues/338 +[#336]: https://github.com/editorconfig/editorconfig-emacs/issues/336 +[#333]: https://github.com/editorconfig/editorconfig-emacs/issues/333 [#330]: https://github.com/editorconfig/editorconfig-emacs/issues/330 [#326]: https://github.com/editorconfig/editorconfig-emacs/issues/326 [#325]: https://github.com/editorconfig/editorconfig-emacs/issues/325
[nongnu] elpa/meow f1bfad9518 2/2: meow-util: fix meow-visit empty-string bug by re-prompting
branch: elpa/meow commit f1bfad9518c2756375e16cd3f9f38235c3f57df8 Author: eshrh Commit: eshrh meow-util: fix meow-visit empty-string bug by re-prompting Fixes the meow-visit empty string bug by re-prompting the user (with an error message) when they give empty input. --- meow-command.el | 2 +- meow-util.el| 7 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/meow-command.el b/meow-command.el index ec56b8283c..e400a10164 100644 --- a/meow-command.el +++ b/meow-command.el @@ -1394,7 +1394,7 @@ To search backward, use \\[negative-argument]." (pos (point)) (text (meow--prompt-symbol-and-words (if arg "Visit backward: " "Visit: ") -(point-min) (point-max))) +(point-min) (point-max) t)) (visit-point (meow--visit-point text reverse))) (if visit-point (let* ((m (match-data)) diff --git a/meow-util.el b/meow-util.el index 76c3a3a3bf..98cc048b54 100644 --- a/meow-util.el +++ b/meow-util.el @@ -272,7 +272,7 @@ Looks up the state in meow-replace-state-name-list" (defun meow--string-join (sep s) (string-join s sep)) -(defun meow--prompt-symbol-and-words (prompt beg end) +(defun meow--prompt-symbol-and-words (prompt beg end &optional disallow-empty) "Completion with PROMPT for symbols and words from BEG to END." (let ((completions)) (save-mark-and-excursion @@ -285,6 +285,11 @@ Looks up the state in meow-replace-state-name-list" (push (format "\\_<%s\\_>" (regexp-quote result)) completions)) (setq completions (delete-dups completions)) (let ((selected (completing-read prompt completions nil nil))) + (while (and (string-empty-p selected) + disallow-empty) +(setq selected (completing-read +(concat "[Input must be non-empty] " prompt) +completions nil nil))) (if meow-visit-sanitize-completion (or (cdr (assoc selected completions)) (regexp-quote selected))
[nongnu] elpa/meow 6a0dc2d2c2 1/2: Revert "meow-command: fix meow-visit bug on empty input (#602)"
branch: elpa/meow commit 6a0dc2d2c2fb3861a6a5b7ba773d41b6c8c7a71c Author: eshrh Commit: eshrh Revert "meow-command: fix meow-visit bug on empty input (#602)" This reverts commit 090f7a4ad3e8085785b991d9e2e135399906911d. --- meow-command.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meow-command.el b/meow-command.el index ed389cc8e4..ec56b8283c 100644 --- a/meow-command.el +++ b/meow-command.el @@ -1395,7 +1395,7 @@ To search backward, use \\[negative-argument]." (text (meow--prompt-symbol-and-words (if arg "Visit backward: " "Visit: ") (point-min) (point-max))) - (visit-point (if (string-empty-p text) nil (meow--visit-point text reverse + (visit-point (meow--visit-point text reverse))) (if visit-point (let* ((m (match-data)) (marker-beg (car m)) @@ -1409,7 +1409,7 @@ To search backward, use \\[negative-argument]." (meow--ensure-visible) (meow--highlight-regexp-in-buffer text) (setq meow--dont-remove-overlay t)) - (message "Visit: %s failed" (if (string-empty-p text) "" text) + (message "Visit: %s failed" text ; ;;; THING
[nongnu] elpa/meow updated (090f7a4ad3 -> f1bfad9518)
elpasync pushed a change to branch elpa/meow. from 090f7a4ad3 meow-command: fix meow-visit bug on empty input (#602) new 6a0dc2d2c2 Revert "meow-command: fix meow-visit bug on empty input (#602)" new f1bfad9518 meow-util: fix meow-visit empty-string bug by re-prompting Summary of changes: meow-command.el | 6 +++--- meow-util.el| 7 ++- 2 files changed, 9 insertions(+), 4 deletions(-)
[elpa] externals/hyperbole 54663e1dcb 1/3: Remove annotated bibliography from table of contents, not included (#537)
branch: externals/hyperbole commit 54663e1dcb2384ec179ee6f23851f9764de54196 Author: Mats Lidell Commit: GitHub Remove annotated bibliography from table of contents, not included (#537) --- DEMO | 1 - 1 file changed, 1 deletion(-) diff --git a/DEMO b/DEMO index 56302a79f3..885c0a0974 100644 --- a/DEMO +++ b/DEMO @@ -457,7 +457,6 @@ command to return to this DEMO later. ** Gitlab (Remote) References ** Git (Local) References ** Grep, Occurrence, Debugger and Compiler Error Buttons, and Cscope Analyzer Lines -** Annotated Bibliography Buttons ** Completion Selection ** Hyperbole Source Buttons ** UNIX Man Apropos Buttons
[elpa] externals/hyperbole c834afd0ee 2/3: Add test for hpath:delimited-possible-path (#536)
branch: externals/hyperbole commit c834afd0ee6c1d74dd370b624f8020af066de86f Author: Mats Lidell Commit: GitHub Add test for hpath:delimited-possible-path (#536) --- ChangeLog | 5 + test/hpath-tests.el | 61 - 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0223a0a542..918302d63e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2024-06-01 Mats Lidell + +* test/hpath-tests.el (hpath--hpath:delimited-possible-path): Add test for +hpath:delimited-possible-path. + 2024-05-31 Mats Lidell * test/hui-tests.el (hui--gbut-should-execute-in-current-folder): Add test diff --git a/test/hpath-tests.el b/test/hpath-tests.el index fa56693a6a..413d755928 100644 --- a/test/hpath-tests.el +++ b/test/hpath-tests.el @@ -3,7 +3,7 @@ ;; Author: Mats Lidell ;; ;; Orig-Date:28-Feb-21 at 23:26:00 -;; Last-Mod: 8-Apr-24 at 16:45:22 by Mats Lidell +;; Last-Mod: 1-Jun-24 at 20:45:10 by Mats Lidell ;; ;; SPDX-License-Identifier: GPL-3.0-or-later ;; @@ -20,6 +20,7 @@ (require 'ert) (require 'hpath) +(require 'el-mock) (require 'hy-test-helpers "test/hy-test-helpers") (declare-function hy-test-helpers:action-key-should-call-hpath:find "hy-test-helpers") @@ -391,5 +392,63 @@ See `hpath:line-and-column-regexp'." (should-not (string-match hpath:line-and-column-regexp "/foo/bar.org:LL1")) (should-not (string-match hpath:line-and-column-regexp "/foo/bar.org:C1"))) +(ert-deftest hpath--hpath:delimited-possible-path () + "Verify delimited path is found in an `ls -R' listings in `shell-mode'." + (let ((files + '(("file1.ext file2.ext file3.ext" ; Space delimited +("file1" "file2" "file3")) + ("file1.ext\tfile2.ext\tfile3.ext" ; Tab delimited +("file1" "file2" "file3")) + ("'file1.ext' 'file2.ext' 'file3.ext'" ; Single quoted +("file1" "file2" "file3")) + ("'file1.ext' file2.ext 'file3.ext'" ; Single quoted mixed +("file1" "file2" "file3")) + ("'file 1.ext' 'file 2.ext' 'file 3.ext'" ; Single quoted with space +("file 1" "file 2" "file 3")) + ("\"file1.ext\" \"file2.ext\" \"file3.ext\"" ; Double quoted +("file1" "file2" "file3")) + ("\"file1.ext\" file2.ext \"file3.ext\"" ; Double quoted mixed +("file1" "file2" "file3")) + ("\"file 1.ext\" \"file 2.ext\" \"file 3.ext\""; Double quoted with space +("file 1" "file 2" "file 3")) + ("\"file1.ext\" 'file2.ext' \"file3.ext\"" ; Mixed quotes 1 +("file1" "file2" "file3")) + ("'file1.ext' \"file2.ext\" 'file3.ext'" ; Mixed quotes 2 +("file1" "file2" "file3")) + (" file1.ext file2.ext file3.ext" ; Leading space +("file1" "file2" "file3")) + ("\tfile1.ext file2.ext file3.ext" ; Leading tab +("file1" "file2" "file3")) + + ;; Failing cases + ;; ("'file1\".ext' 'file2\".ext' 'file3\".ext'"; Single quoted with double quote + ;; ("file1\"" "file2\"" "file3\"")) + ;; ("\"file1'.ext\" \"file2'.ext\" \"file3'.ext\"" ; Double quoted with single quote + ;; ("file1'" "file2'" "file3'")) + ))) +(dolist (fls files) + (with-temp-buffer +(insert "\ +$ ls -R dir +dir/subdir: +" (car fls)) +(goto-char (point-min)) +(shell-mode) +(dolist (v (cadr fls)) + (let ((filename v)) +(search-forward filename) +(should (looking-at-p "\\.ext")) +(mocklet (((file-exists-p "dir/subdir") => t)) + (should (string= (expand-file-name (concat filename ".ext") "dir/subdir") + (hpath:delimited-possible-path)) + (provide 'hpath-tests) + +:; This file can't be byte-compiled without the `el-mock' package +;; which is not a dependency of Hyperbole. +;; +;; Local Variables: +;; no-byte-compile: t +;; End: + ;;; hpath-tests.el ends here
[elpa] externals/hyperbole updated (06fdacc1ba -> c3050387ea)
elpasync pushed a change to branch externals/hyperbole. from 06fdacc1ba Verify global button executes in current folder (#533) new 54663e1dcb Remove annotated bibliography from table of contents, not included (#537) new c834afd0ee Add test for hpath:delimited-possible-path (#536) new c3050387ea Add test cases for hywiki (#534) Summary of changes: ChangeLog| 13 + DEMO | 1 - test/hpath-tests.el | 61 ++- test/hywiki-tests.el | 138 +++ 4 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 test/hywiki-tests.el
[elpa] externals/hyperbole c3050387ea 3/3: Add test cases for hywiki (#534)
branch: externals/hyperbole commit c3050387ea625842e2fa93fa9d7f44bd8d0c1e35 Author: Mats Lidell Commit: GitHub Add test cases for hywiki (#534) --- ChangeLog| 8 +++ test/hywiki-tests.el | 138 +++ 2 files changed, 146 insertions(+) diff --git a/ChangeLog b/ChangeLog index 918302d63e..3ea46df538 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2024-06-01 Mats Lidell +* test/hywiki-tests.el (hywiki-tests--hywiki-add-page--adds-file-in-wiki-folder) +(hywiki-tests--hywiki-add-page--adds-no-wiki-word-fails) +(hywiki-tests--wikiword-with-prefix-creates-a-new-page) +(hywiki-tests--not-a-wikiword-unless-in-hywiki-mode) +(hywiki-tests--face-property-for-wikiword-with-wikipage) +(hywiki-tests--no-face-property-for-no-wikipage): Add test cases for +hywiki. + * test/hpath-tests.el (hpath--hpath:delimited-possible-path): Add test for hpath:delimited-possible-path. diff --git a/test/hywiki-tests.el b/test/hywiki-tests.el new file mode 100644 index 00..ee8b282140 --- /dev/null +++ b/test/hywiki-tests.el @@ -0,0 +1,138 @@ +;;; hywiki-tests.el --- one line summary-*- lexical-binding: t; -*- +;; +;; Author: Mats Lidell +;; +;; Orig-Date:18-May-24 at 23:59:48 +;; Last-Mod: 1-Jun-24 at 16:16:00 by Mats Lidell +;; +;; SPDX-License-Identifier: GPL-3.0-or-later +;; +;; Copyright (C) 2021-2022 Free Software Foundation, Inc. +;; See the "HY-COPY" file for license information. +;; +;; This file is part of GNU Hyperbole. + +;;; Commentary: +;; + +;;; Code: + +(require 'ert) +(require 'el-mock) +(require 'hy-test-helpers) +(require 'hywiki) + +(ert-deftest hywiki-tests--hywiki-add-page--adds-file-in-wiki-folder () + "Verify add page creates file in wiki folder and sets hash table." + (let ((hsys-org-enable-smart-keys t) +(hywiki-directory (make-temp-file "hywiki" t)) +(hywiki--pages-hasht nil)) +(unwind-protect +(progn + (mocklet (((make-empty-file (expand-file-name "WikiWord.org" hywiki-directory) t) => t)) +(should (string= (expand-file-name "WikiWord.org" hywiki-directory) + (hywiki-add-page "WikiWord" + ;; Verify hash table is updated + (with-mock +(not-called hywiki-add-page) +(should (string= (expand-file-name "WikiWord.org" hywiki-directory) + (hywiki-get-page "WikiWord") + (hy-delete-dir-and-buffer hywiki-directory + +(ert-deftest hywiki-tests--hywiki-add-page--adds-no-wiki-word-fails () + "Verify add page requires a WikiWord." + :expected-result :failed + ;; Should not leave erroneously created file after test but leaving + ;; added error cleanup till later if it is even needed!? No file + ;; should be created so only happens on error!? (If this is + ;; considered an error case that is.) + (let ((hywiki-directory (make-temp-file "hywiki" t)) +(hywiki--pages-hasht nil)) +(unwind-protect +(should-error (hywiki-add-page "notawikiword")) + (hy-delete-dir-and-buffer hywiki-directory + +(ert-deftest hywiki-tests--wikiword-with-prefix-creates-a-new-page () + "Verify `action-key' on a prefixed WikiWord, outside of hywiki-directory, creates a new page." + (defvar wikifile) + (let ((hsys-org-enable-smart-keys t) +(hywiki-directory (make-temp-file "hywiki" t)) +(hywiki--pages-hasht nil) +(wikifile (make-temp-file "wikifile"))) +(hywiki-mode -1) +(unwind-protect +(with-temp-buffer + (insert "[[hy:WikiWord]]") + (goto-char 4) + (mocklet (((hywiki-add-page "WikiWord") => wikifile)) +(action-key))) + (hy-delete-file-and-buffer wikifile + +(ert-deftest hywiki-tests--not-a-wikiword-unless-in-hywiki-mode () + "Verify WikiWord is not a WikiWord unless in `hywiki-mode'." + (let ((hsys-org-enable-smart-keys t) +(hywiki-directory (make-temp-file "hywiki" t)) +(hywiki--pages-hasht nil)) +(unwind-protect +(with-temp-buffer + (insert "WikiWord") + (goto-char 4) + (hywiki-mode -1) + (should-not (hywiki-at-wikiword)) + (hywiki-mode) + (should (string= "WikiWord" (hywiki-at-wikiword + (hywiki-mode -1) + (hy-delete-dir-and-buffer hywiki-directory + +;; Following two test cases for verifying proper face is some what +;; experimental. They need to be run in interactive mode and with the +;; help of hy-test-helpers:consume-input-events it seems the property +;; can be verified. In the middle of it the "*ert*" buffer gets +;; swapped in and the temp buffer needs to be brought back!? + +(ert-deftest hywiki-tests--face-property-for-wikiword-with-wikipage () + "Verify WikiWord for a wiki page gets face property hywiki-word-face." + (skip-unless (not noninteractive)) + (let* ((hsys-org-enable-smart-keys t) +
[elpa] externals/org-modern 0b7af08548 2/2: Version 1.3
branch: externals/org-modern commit 0b7af08548e586c0d3b0ca4a683253da407220d1 Author: Daniel Mendler Commit: Daniel Mendler Version 1.3 --- CHANGELOG.org | 2 +- org-modern.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.org b/CHANGELOG.org index e6d6aa9e9f..40352d3d5b 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -2,7 +2,7 @@ #+author: Daniel Mendler #+language: en -* Development +* Version 1.3 (2024-06-02) - Add support for heading folding indicators. The option ~org-modern-star~ has been changed to accept the values ~fold~, ~replace~ and ~nil~. Set ~org-modern-star~ diff --git a/org-modern.el b/org-modern.el index fc387f2e8e..b4a0927610 100644 --- a/org-modern.el +++ b/org-modern.el @@ -5,7 +5,7 @@ ;; Author: Daniel Mendler ;; Maintainer: Daniel Mendler ;; Created: 2022 -;; Version: 1.2 +;; Version: 1.3 ;; Package-Requires: ((emacs "27.1") (compat "29.1.4.4")) ;; Homepage: https://github.com/minad/org-modern ;; Keywords: outlines, hypermedia, text
[elpa] externals/org-modern a01cbbd224 1/2: Update changelog
branch: externals/org-modern commit a01cbbd22459bb026acfc87f9754e889a22f566f Author: Daniel Mendler Commit: Daniel Mendler Update changelog --- CHANGELOG.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.org b/CHANGELOG.org index fa4bc6573d..e6d6aa9e9f 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -5,7 +5,8 @@ * Development - Add support for heading folding indicators. The option ~org-modern-star~ has - been changed to accept the values ~fold~, ~replace~ and ~nil~. + been changed to accept the values ~fold~, ~replace~ and ~nil~. Set ~org-modern-star~ + to ~replace~ to go back to the old default behavior. - Add new customization options ~org-modern-replace-stars~ and ~org-modern-fold-stars~. - Add ~org-modern-tag-faces~.
[elpa] externals/org-modern updated (2c47e4cd5d -> 0b7af08548)
elpasync pushed a change to branch externals/org-modern. from 2c47e4cd5d org-modern--cycle: Install hook only if org-modern-star=fold new a01cbbd224 Update changelog new 0b7af08548 Version 1.3 Summary of changes: CHANGELOG.org | 5 +++-- org-modern.el | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-)
[nongnu] elpa/cider updated (d430ab314f -> 5f79b02fda)
elpasync pushed a change to branch elpa/cider. from d430ab314f [complete] Prioritize flex style if flex style is requested new 49496142e3 [complete] Add a comment about flex style priority new b842f0df07 Use cider-nrepl 0.49.0 new 5f79b02fda [inspector] Add function and binding for toggling view mode Summary of changes: CHANGELOG.md | 8 ++-- cider-completion.el| 2 + cider-inspector.el | 9 + cider.el | 2 +- dev/docker-sample-project/project.clj | 2 +- dev/tramp-sample-project/project.clj | 2 +- .../ROOT/pages/basics/middleware_setup.adoc| 12 +++--- doc/modules/ROOT/pages/basics/up_and_running.adoc | 4 +- doc/modules/ROOT/pages/cljs/shadow-cljs.adoc | 2 +- doc/modules/ROOT/pages/cljs/up_and_running.adoc| 4 +- doc/modules/ROOT/pages/debugging/inspector.adoc| 4 ++ test/cider-tests.el| 44 +++--- 12 files changed, 56 insertions(+), 39 deletions(-)
[nongnu] elpa/cider 49496142e3 1/3: [complete] Add a comment about flex style priority
branch: elpa/cider commit 49496142e36db47b1abedf2cf087a24382b8cdde Author: Oleksandr Yakushev Commit: Oleksandr Yakushev [complete] Add a comment about flex style priority --- cider-completion.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cider-completion.el b/cider-completion.el index a2a91ae57d..8e92714547 100644 --- a/cider-completion.el +++ b/cider-completion.el @@ -297,6 +297,8 @@ Only affects the `cider' completion category.`" (unless found-styles (setq found-styles '(styles basic))) (unless (member 'flex found-styles) + ;; This expression makes sure that 'flex style has a priority over other + ;; styles, see https://github.com/clojure-emacs/cider/pull/3696. (setq found-styles (apply #'list 'styles 'flex (cdr found-styles (add-to-list 'completion-category-overrides (apply #'list 'cider found-styles (when found-cycle (list found-cycle))
[nongnu] elpa/cider b842f0df07 2/3: Use cider-nrepl 0.49.0
branch: elpa/cider commit b842f0df07d01b63cf5fe124f3f847da6bfa7d26 Author: Oleksandr Yakushev Commit: Oleksandr Yakushev Use cider-nrepl 0.49.0 --- CHANGELOG.md | 6 +-- cider.el | 2 +- dev/docker-sample-project/project.clj | 2 +- dev/tramp-sample-project/project.clj | 2 +- .../ROOT/pages/basics/middleware_setup.adoc| 12 +++--- doc/modules/ROOT/pages/basics/up_and_running.adoc | 4 +- doc/modules/ROOT/pages/cljs/shadow-cljs.adoc | 2 +- doc/modules/ROOT/pages/cljs/up_and_running.adoc| 4 +- test/cider-tests.el| 44 +++--- 9 files changed, 39 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54ef88a462..766c8b4d82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ### Changes +- Bump the injected `cider-nrepl` to [0.49.0](https://github.com/clojure-emacs/cider-nrepl/blob/master/CHANGELOG.md#0490-2024-06-02). + ### Bugs fixed - [#3696](https://github.com/clojure-emacs/cider/pull/3696): Don't eagerly complete a candidate if there are other candidates matching `flex` style. @@ -27,6 +29,7 @@ - adds `cider-ns-code-reload-tool` defcustom, defaulting to `'tools.namespace`. - you can change it to `'clj-reload` to use [clj-reload](https://github.com/tonsky/clj-reload) instead of [tools.namespace](https://github.com/clojure/tools.namespace). - [#3682](https://github.com/clojure-emacs/cider/issues/3682): Add `cider-jack-in` support for [Basilisp](https://github.com/basilisp-lang/basilisp) (Python). +- [#3664](https://github.com/clojure-emacs/cider/issues/3664): Add customization inspector op to change max nested collection depth. ### Changes @@ -34,11 +37,8 @@ - [#3628](https://github.com/clojure-emacs/cider/issues/3628): `cider-ns-refresh`: summarize errors as an overlay. - [#3660](https://github.com/clojure-emacs/cider/issues/3660): Fix `cider-inspector-def-current-val` always defining in `user` namespace. - [#3661](https://github.com/clojure-emacs/cider/issues/3661): Truncate echo area output ahead of time. -- [#3664](https://github.com/clojure-emacs/cider/issues/3664): Add customization inspector op to change max nested collection depth. - Bump the injected `enrich-classpath` to [1.19.3](https://github.com/clojure-emacs/enrich-classpath/compare/v1.19.0...v1.19.3). - Bump the injected nREPL to [1.1.2](https://github.com/nrepl/nrepl/releases/tag/v1.1.2). -- Bump the injected `cider-nrepl` to [0.48.0](https://github.com/clojure-emacs/cider-nrepl/blob/v0.48.0/CHANGELOG.md#0480-2024-05-13). - - Updates [Orchard](https://github.com/clojure-emacs/orchard/blob/v0.23.2/CHANGELOG.md#0232-2024-03-10). - Bump the injected `cider-nrepl` to [0.48.0](https://github.com/clojure-emacs/cider-nrepl/blob/master/CHANGELOG.md#0480-2024-05-13). - Updates [clj-reload](https://github.com/tonsky/clj-reload/blob/0.6.0/CHANGELOG.md#060---may-3-2024). - Updates [tools.reader](https://github.com/clojure/tools.reader/blob/master/CHANGELOG.md). diff --git a/cider.el b/cider.el index ba7013f9e5..67e83bd5e8 100644 --- a/cider.el +++ b/cider.el @@ -567,7 +567,7 @@ the artifact.") Used when `cider-jack-in-auto-inject-clojure' is set to `latest'.") -(defconst cider-required-middleware-version "0.48.0" +(defconst cider-required-middleware-version "0.49.0" "The CIDER nREPL version that's known to work properly with CIDER.") (defcustom cider-injected-middleware-version cider-required-middleware-version diff --git a/dev/docker-sample-project/project.clj b/dev/docker-sample-project/project.clj index 1d5ff61d86..01dc35412f 100644 --- a/dev/docker-sample-project/project.clj +++ b/dev/docker-sample-project/project.clj @@ -2,4 +2,4 @@ :dependencies [[org.clojure/clojure "1.11.1"] [clj-http "3.12.3"]] :source-paths ["src"] - :plugins [[cider/cider-nrepl "0.48.0"]]) + :plugins [[cider/cider-nrepl "0.49.0"]]) diff --git a/dev/tramp-sample-project/project.clj b/dev/tramp-sample-project/project.clj index bc337231c6..edf9464f55 100644 --- a/dev/tramp-sample-project/project.clj +++ b/dev/tramp-sample-project/project.clj @@ -2,5 +2,5 @@ :dependencies [[org.clojure/clojure "1.11.1"] [clj-http "3.12.3"]] :source-paths ["src"] - :plugins [[cider/cider-nrepl "0.48.0"] + :plugins [[cider/cider-nrepl "0.49.0"] [refactor-nrepl "3.9.0"]]) diff --git a/doc/modules/ROOT/pages/basics/middleware_setup.adoc b/doc/modules/ROOT/pages/basics/middleware_setup.adoc index 5c46dad8ce..1898d017a9 100644 --- a/doc/modules/ROOT/pages/basics/middleware_setup.adoc +++ b/doc/modules/ROOT/pages/basics/middleware_setup.adoc @@ -32,14 +32,14 @@ Use the convenient plugin for defaults, either in your project's [source,clojure] -:plugins [[cider/cider-nrepl "0.48.0"]] +:plugins [[cider/cider-nrepl "0.49.0"]] A minimal `pr
[nongnu] elpa/cider 5f79b02fda 3/3: [inspector] Add function and binding for toggling view mode
branch: elpa/cider commit 5f79b02fda70179349ba34a4fed1436708c669c3 Author: Oleksandr Yakushev Commit: Oleksandr Yakushev [inspector] Add function and binding for toggling view mode --- CHANGELOG.md| 2 ++ cider-inspector.el | 9 + doc/modules/ROOT/pages/debugging/inspector.adoc | 4 3 files changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 766c8b4d82..a31a978d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### New features +- [#3692](https://github.com/clojure-emacs/cider/pull/3692): Add ability to switch view modes in the ispector (bound to `v`). + ### Changes - Bump the injected `cider-nrepl` to [0.49.0](https://github.com/clojure-emacs/cider-nrepl/blob/master/CHANGELOG.md#0490-2024-06-02). diff --git a/cider-inspector.el b/cider-inspector.el index dee9540111..ad01097392 100644 --- a/cider-inspector.el +++ b/cider-inspector.el @@ -124,6 +124,7 @@ by clicking or navigating to them by other means." (define-key map "a" #'cider-inspector-set-max-atom-length) (define-key map "c" #'cider-inspector-set-max-coll-size) (define-key map "C" #'cider-inspector-set-max-nested-depth) +(define-key map "v" #'cider-inspector-toggle-view-mode) (define-key map "d" #'cider-inspector-def-current-val) (define-key map "t" #'cider-inspector-tap-current-val) (define-key map "1" #'cider-inspector-tap-at-point) @@ -353,6 +354,14 @@ MAX-NESTED-DEPTH is the new value." (when (nrepl-dict-get result "value") (cider-inspector--render-value result 'v2 +(defun cider-inspector-toggle-view-mode () + "Toggle the view mode of the inspector between normal and object view mode." + (interactive) + (let ((result (cider-nrepl-send-sync-request `("op" "inspect-toggle-view-mode") + cider-inspector--current-repl))) +(when (nrepl-dict-get result "value") + (cider-inspector--render-value result 'v2 + (defcustom cider-inspector-preferred-var-names nil "The preferred var names to be suggested by `cider-inspector-def-current-val'. diff --git a/doc/modules/ROOT/pages/debugging/inspector.adoc b/doc/modules/ROOT/pages/debugging/inspector.adoc index fc82481dc9..72bc376e1d 100644 --- a/doc/modules/ROOT/pages/debugging/inspector.adoc +++ b/doc/modules/ROOT/pages/debugging/inspector.adoc @@ -76,6 +76,10 @@ You'll have access to additional keybindings in the inspector buffer | `cider-inspector-set-max-atom-length` | Set a new maximum length above which nested atoms (non-collections) are truncated +| kbd:[v] +| `cider-inspector-toggle-view-mode` +| Switch the rendering of the current value between `:normal` and `:object` view mode. In `:object` mode, any value is rendered as a plain Java object (by displaying its fields) instead of custom rendering rules that the Inspector applies in `:normal` mode. + | kbd:[d] | `cider-inspector-def-current-val` | Defines a var in the REPL namespace with current inspector value. If you tend to always choose the same name(s), you may want to set the `cider-inspector-preferred-var-names` customization option.
[nongnu] elpa/csv2ledger 09e02e84a5 036/190: Expand README.md
branch: elpa/csv2ledger commit 09e02e84a5c5d5ec0236193e2933004f60d4dcb6 Author: Joost Kremers Commit: Joost Kremers Expand README.md --- README.md | 38 +++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 78d2960dcb..193ae4078b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The second option you should set is `c2l-csv-columns`. This defines the columns (date valuation description sender payee amount) ``` -This means that the first column contains the date, the second the valuation, etc. You should change this list to whatever is correct for the CSV files you want to read. In order to create a proper ledger entry, your file should at least contain `date`, `sender`, `payee` and `amount`. The `valuation` and `description` fields can be added to the entry if they exist, but if not, they are left out. +This means that the first column contains the date, the second the valuation, etc. You should change this list to whatever is correct for the CSV files you want to read. In order to create a proper ledger entry, your file should at least contain `date`, `sender`, `payee` and `amount`. The `valuation` and `description` fields are added to the entry if they exist, but if not, they are left out. If there are columns in your CSV files that you do not need for the ledger entry, you can write and underscore for them. For example, this is the setting that I use for my CSV files: @@ -76,7 +76,39 @@ By default, `csv2ledger` only checks the `payee` and `description` fields in the (setq c2l-title-match-fields '(description payee sender type)) ``` -This means that the `description` field is checked first, then the `payee`, then the `sender` and lastly the `type` field. The `type` field is not part of the default setup, but it is listed in the CSV files I get from my bank and it indicates whether the transaction was a bank transfer, a recurrent order, an ATM withdrawal, a card payment at a store, etc. I have a matcher that captures ATM withdrawals that sets the target account to `Assets:Cash`. +This means that the `description` field is checked first, then the `payee`, then the `sender` and lastly the `type` field. The `type` field is not part of the default setup, but it is listed in the CSV files I get from my bank and it indicates whether the transaction was a bank transfer, an ATM withdrawal, a card payment at a store, etc. I have a matcher that captures ATM withdrawals that sets the target account to `Assets:Cash`. -Note that this is the *only* reason for including the `type` field in `c2l-csv-columns` above: I use its value to help determine the target account. +Note that this is the *only* reason for including the `type` field in `c2l-csv-columns` above: I use its value to help determine the target account. As mentioned, the `type` field is not included in the ledger entry. +## Modifying field values ## + +Depending on the format of your CSV file, it may also be necessary to set the variable `c2l-field-parse-functions`. This is a list mapping fields to functions that take the field's value and convert it to something else. For example, my CSV files provide the date in the format `DD.MM.`, but ledger expects them to be in the format `-MM-DD`. `csv2ledger` comes with a function that performs this conversion, `c2l-convert-little-endian-to-iso8601-date`. I therefore set `c2l-field-pars [...] + +``` +(setq c2l-field-parse-functions + '((date . c2l-convert-little-endian-to-iso8601-date))) +``` + +I have a similar problem with the amount. In the CSV file, amounts are given as follows: `3.150,20 €` or `-240,71 €`. I need to remove the dots and replace the decimal comma with a decimal dot. Furthermore, in my ledger file, the commodity € comes before the amount, but after the minus sign. + +Since this is a very particular conversion, there is no function for it included in `csv2ledger`, but if you face the same problem, you can use the following (or adapt it, if your problem is similar): + +``` +(defun c2l-convert-postbank-to-ledger-amount (amount) + "Convert AMOUNT from the format found in Postbank CSV files to ledger format. +Specifically, this converts an amount of the form \"-3.150,20 €\" +to \"-€3150.20\"." + (string-match "\\(-\\)?\\([[:digit:].]+\\),\\([[:digit:]]\\{2\\}\\)" amount) + (let ((sign (or (match-string 1 amount) "")) +(euros (string-replace "." "" (match-string 2 amount))) +(cents (match-string 3 amount))) +(concat sign "€" euros "." cents))) +``` + +You can then add this to `c2l-field-parse-functions`: + +``` +(setq c2l-field-parse-functions + '((date . c2l-convert-little-endian-to-iso8601-date) +(amount . c2l-convert-postbank-to-ledger-amount))) +```
[nongnu] elpa/csv2ledger f19910d17b 099/190: Add option c2l-entry-function.
branch: elpa/csv2ledger commit f19910d17b283c8564f9d9294e11e723834fbabd Author: Joost Kremers Commit: Joost Kremers Add option c2l-entry-function. Also rename c2l--compose-entry to c2l-compose-entry (with one dash), because this change makes it a public function. --- csv2ledger.el | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index f38f523fa2..997ca69a41 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -160,6 +160,14 @@ returned is used as the amount of the ledger entry." :group 'csv2ledger :set-after '(c2l-csv-columns)) +(defcustom c2l-entry-function #'c2l-compose-entry + "Function to create a ledger entry. +This should be a function that takes an alist of field-value +pairs and returns a string. The string should be a formatted +Ledger entry." + :type 'function + :group 'csv2ledger) + (defcustom c2l-account-matchers-file nil "File containing matcher strings mapped to accounts. This should be a TSV (tab-separated values) file containing one @@ -280,7 +288,7 @@ make sure to add one using `c2l-field-parse-functions'." "Return non-nil is STR is likely to be an amount." (string-match-p "[0-9]+[0-9.,]*[.,][0-9]\\{2\\}" str)) -(defun c2l--compose-entry (transaction) +(defun c2l-compose-entry (transaction) "Create a ledger entry. TRANSACTION is an alist containing (key . value) pairs that will be included in the entry. It should at least contain values for @@ -392,7 +400,7 @@ already, present, its value is updated." (if (assq 'amount modified-fields) (setf (alist-get 'amount modified-fields) amount) (push (cons 'amount amount) modified-fields)) -(c2l--compose-entry modified-fields))) +(funcall c2l-entry-function modified-fields))) (defun c2l--get-current-row () "Read the current line as a CSV row.
[nongnu] elpa/csv2ledger c051099f45 149/190: Update the README
branch: elpa/csv2ledger commit c051099f454c99fa60fbe6a3cde80beb9ed73f49 Author: Joost Kremers Commit: Joost Kremers Update the README --- README.md | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 444d295700..1c49e7c4c6 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ If you have this information in your CSV file, you can use it and add it to the For the moment, `csv2ledger` needs to be installed manually. Put the file `csv2ledger.el` in your load path, byte-compile it if you wish, and `require` it in your init file. -Make sure to install the dependencies as well: `csv-mode` from GNU ELPA, and `parse-csv` and `dash` from Melpa. Note that for `csv2ledger` to work properly, CSV files must be opened in buffers with `csv-mode` as the major mode. This should work automatically after installing the `csv-mode` package, but if you have issues, make sure to check this. +Make sure to install the dependencies as well: `csv-mode` from GNU ELPA, `dash` from GNU ELPA or MELPA, and `parse-csv` from MELPA. Note that for `csv2ledger` to work properly, CSV files must be opened in buffers with `csv-mode` as the major mode. This should work automatically after installing the `csv-mode` package, but if you have issues, make sure to check this. ## Customisation ## @@ -76,7 +76,7 @@ In the default setup, all these fields (except the underscore, obviously) may be The `payee` and `sender` columns never appear both. By default, `payee` is used as the title of the ledger entry and `sender` is ignored. If you set the option `c2l-account-holder` however, the `sender` will be used as the title for transactions in which you are the payee, i.e., when you receive money. If you do not have a `sender` field in your CSV files, you may simply leave it out. In that case, the `payee` will always be used as the title (at least in the default setup). -The `amount` field is intended for the CSV field that contains the amount of the transaction. If your CSV files have two separate columns for amounts credit and amounts debit, use the column names `credit` and `debit` instead. `csv2ledger` then checks for each transaction which one of those fields actually contains an amount and uses that to create the ledger entry. Note that in this case, it is assumed that the `debit` field contains a negative amount, i.e., that it has a minus sign. If [...] +The `amount` field is intended for the CSV field that contains the amount of the transaction. If your CSV files have two separate columns for amounts credit and amounts debit, use the column names `credit` and `debit` instead. `csv2ledger` then checks for each transaction which one of those fields actually contains an amount and uses that to create the ledger entry. Note that in this case, it is assumed that the `debit` field contains a negative amount, i.e., that it has a minus sign. If [...] The `description` and `posted` fields are entirely optional. If you have them and wish to include them in the ledger entry, add them to `c2l-csv-columns`. If you do not wish them included in the ledger entries, ignore them. @@ -88,7 +88,7 @@ As an example example, this is my setting for `c2l-csv-columns` (keep in mind th The CSV files from my bank have an effective (posted) date in the second column, but it is almost always identical to the booking date and does not provide me with any useful information. Furthermore, they also have an additional final column with the account balance, which `csv2ledger` doesn't use. So I use an underscore for both these columns. -Note that I have a `type` field in this list, which is not one of the fields that are meaningful to `csv2ledger`. You can, in fact, add any field to `c2l-csv-columns` that you like. By default, `csv2ledger` does not do anything with such user-defined fields, but with some additional configuration, you can make use of them in several ways. In my CSV files, the column that I label`type` indicates whether the transaction is a bank transfer, an ATM withdrawal, a card payment at a store, etc. [...] +Note that I have a `type` field in this list, which is not one of the fields listed above. You can, in fact, add custom fields to `c2l-csv-columns`. By default, `csv2ledger` does not do anything with such user-defined fields, but with some additional configuration, you can make use of them in several ways. In my CSV files, the column that I label `type` indicates whether the transaction is a bank transfer, an ATM withdrawal, a card payment at a store, etc. I use this information to captu [...] ## Running the conversion ## @@ -97,9 +97,9 @@ With these options set up, it is possible to convert a CSV file. To do so, open There is also the command `c2l-csv-entry-as-kill`: this converts the single entry that point is on and places the result in the kill ring. It also displays the entry in the echo area so y
[nongnu] elpa/csv2ledger e8a7609736 050/190: Add user option `c2l-alignment-column`.
branch: elpa/csv2ledger commit e8a7609736651361c6814f606eb5ca8338287c53 Author: Joost Kremers Commit: Joost Kremers Add user option `c2l-alignment-column`. --- csv2ledger.el | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index a44b2dfe59..14daf842cf 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -139,6 +139,13 @@ returns a match wins." :type 'boolean :group 'csv2ledger) +(defcustom c2l-alignment-column 52 + "The column to which amounts are aligned. +This should most likely be set to the same value as +`ledger-post-amount-alignment-column'." + :type 'integer + :group 'csv2ledger) + (defvar c2l--accounts nil "List of ledger accounts, mainly used for completion.") (defvar c2l--compiled-matcher-regexes nil "Alist of accounts and their matchers.") (defvar c2l--results-buffer nil "Buffer for conversion results.") @@ -183,8 +190,7 @@ reversed. FROM and TO default to `c2l-fallback-account' and `c2l-base-account', respectively." (or from (setq from c2l-fallback-account)) (or to (setq to c2l-base-account)) - (let* ((width ledger-post-amount-alignment-column) - (parsed-items (mapcar (lambda (item) + (let* ((parsed-items (mapcar (lambda (item) (let ((field (car item)) (value (cdr item))) (cons field @@ -196,7 +202,7 @@ reversed. FROM and TO default to `c2l-fallback-account' and (if (and .description (not (string-empty-p .description))) (format "; Desc: %s\n" .description) "") (format "%s\n" from) (format "%s " to) - (make-string (- width 4 (length to) 2 (length .amount)) ?\s) + (make-string (- c2l-alignment-column 4 (length to) 2 (length .amount)) ?\s) .amount "\n" (defun c2l--read-accounts (file)
[nongnu] elpa/csv2ledger 5f270d2ff0 132/190: Update the README.
branch: elpa/csv2ledger commit 5f270d2ff072aba9d36d28ca11eb9da344756c68 Author: Joost Kremers Commit: Joost Kremers Update the README. --- README.md | 18 ++ 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 014b9c64e1..8366628db8 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,7 @@ If you have this information in your CSV file, you can use it and add it to the For the moment, `csv2ledger` needs to be installed manually. Put the file `csv2ledger.el` in your load path, byte-compile it if you wish, and `require` it in your init file. -Make sure to install the dependencies as well: `csv-mode` from GNU ELPA, and `parse-csv` and `dash` from Melpa. Note that for `csv2ledger` to work properly, CSV files must be opened in buffers with `csv-mode` as the major mode. This should work automatically after installing `csv-mode`, but if you have issues, make sure to check this. - -The advantage of `csv-mode` is that it will also handle CSV files that use semicolon or TAB as separator (even if they have a `.csv` suffix). The separator should be recognised automatically without any user intervention. +Make sure to install the dependencies as well: `csv-mode` from GNU ELPA, and `parse-csv` and `dash` from Melpa. Note that for `csv2ledger` to work properly, CSV files must be opened in buffers with `csv-mode` as the major mode. This should work automatically after installing the `csv-mode` package, but if you have issues, make sure to check this. ## Customisation ## @@ -58,7 +56,6 @@ Several customisation options are present. The full list with a short explanatio - `c2l-alignment-column` (`52`) — Column to which the amount is aligned. - ## Setup ## At the very least, you will need to set two user options: `c2l-base-account` and `c2l-csv-columns`. `c2l-base-account` is the account that represents the bank account in your ledger file. By default, it is set to the value `"Assets:Checking"`. @@ -100,6 +97,10 @@ With these options set up, it is possible to convert a CSV file. To do so, open There is also the command `c2l-csv-entry-as-kill`: this converts the single entry that point is on and places the result in the kill ring. It also displays the entry in the echo area so you can see what it is doing. This is an easy way of testing if your conversion settings are correct. +`csv2ledger` expects that `csv-mode` is used as the major mode for the buffer visiting your CSV file, and `parse-csv` to parse the contents of the CSV file. This means it is able to automatically handle CSV files that use a semicolon as separator instead of a comma, and also TSV files, which use the TAB character as separator. In addition, `csv2ledger` tries to determine if the first line of the CSV file is a header line or not, by looking at the `amount`, `debit` and `credit` fields and [...] + +You should make sure, however, that all the data in the file is CSV data. Some banks place some additional information at the top of the file (such as account number, total balance, etc.) that is not part of the CSV data. If this is the case, `csv-mode` may have trouble determining the separator, so it is usually best to remove this data and reread the file. Alternatively, do `M-x csv-set-separator` to set the correct separator and then use `c2l-convert-region` for the data that you want [...] + ## Setting the target account ## @@ -184,9 +185,9 @@ Another possible use of `c2l-field-modify-functions` is to make sure the value o ### Modifying the transaction ### -One potential disadvantage of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of some other field or fields in the transaction. If you need to make such a change to the transaction, you can set the option `c2l-transaction-modify-functions` to a list of functions that take the entire transaction as its argument and return a modified transaction. +One limitation of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of some other field or fields in the transaction. If you need to make such a change, you add a function to the option `c2l-transaction-modify-functions`. This option holds a list of functions that take the entire transaction as its argument and return a modified transaction. -The transaction is passed as an alist of field-value pairs. For example, for the ledger entry shown above, the transaction would be as follows: +The transaction is passed as an alist of field-value pairs, with the fields being symbols and the values being strings. For example, for the ledger entry shown above, the transaction would be as follows: ``` ((date . "2022-20-17") @@ -198,7 +199,7 @@ The transaction is passed a
[nongnu] elpa/csv2ledger b0da62c00b 153/190: Small update to the README
branch: elpa/csv2ledger commit b0da62c00be7e1b4ee8a17a3a7831dd572d19fc2 Author: Joost Kremers Commit: Joost Kremers Small update to the README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fe4bad676a..ecd7168e15 100644 --- a/README.md +++ b/README.md @@ -256,3 +256,5 @@ This will apply all listed `c2l` settings to all CSV files in the directory in c If you prefer to keep your `csv2ledger` configuration in your init file, you can use the functions `dir-locals-set-directory-class` and `dir-locals-set-class-variables` to set up directory-local variables for specific directories. The Info node mentioned above explains how to do this. One (small) disadvantage of this approach is that some of the customisation options are considered unsafe or risky by Emacs, so when you open a CSV file, Emacs will ask you if you want to apply them. If you tell Emacs to apply them and set them as safe for future use, you'll only see that question once for a directory, however. + +Keep in mind that if you set an option in your init file, it will be used in every CSV file you open, unless you override that setting in a `.dir-locals.el` file. This means that if you have settings that you want to apply to all CSV files, you can set them in your init file, instead of having to repeat the option in every `.dir-locals.el` file you create.
[nongnu] elpa/csv2ledger c8ee0a4d50 152/190: Fix typo in README
branch: elpa/csv2ledger commit c8ee0a4d5022bcf9d8b3168d656ca4dabbe100a4 Author: Joost Kremers Commit: Joost Kremers Fix typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b8893981f..fe4bad676a 100644 --- a/README.md +++ b/README.md @@ -246,7 +246,7 @@ How to set up directory-local variables is discussed in the Emacs manual (see th ((csv-mode . ((c2l-accounts-file . "~/Finances/Accounts.ledger") (c2l-account-matchers-file . "~/Finances/Account_matchers.tsv") (c2l-base-account . "Assets:Checking") - (c2l-fallback-account . "Expenses:Faalback") + (c2l-fallback-account . "Expenses:Fallback") (c2l-csv-columns . (date _ type description payee amount _)) (c2l-auto-cleared . t ```
[nongnu] elpa/csv2ledger a1b0dd35e1 053/190: Update README.
branch: elpa/csv2ledger commit a1b0dd35e1fa450641168fab7fb27e362af963c0 Author: Joost Kremers Commit: Joost Kremers Update README. Add `c2l-alignment-column`. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e2a3aeb6fd..33b3108210 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,9 @@ You can then add this to `c2l-field-parse-functions`: (amount . c2l-convert-postbank-to-ledger-amount))) ``` +A final variable you may want to set is `c2l-alignment-column`. This should most likely have the same value as `ledger-post-amount-alignment-column`, although `csv2ledger` currently assumes that `ledger-post-amount-alignment-at` is set to `:end` and that the commodity precedes the amount. If either is not true, alignment is probably not optimal. + + ## Doing the conversion ## There are three commands to convert CSV lines to ledger entries: `c2l-csv-entry-as-kill` converts the entry point is on and puts the result in the kill ring. It also displays the entry in the echo area so you can see what it is doing.
[nongnu] elpa/csv2ledger f536bca1bf 040/190: New function `c2l-get-results-buffer`.
branch: elpa/csv2ledger commit f536bca1bfb88d78bd547df2d229a3e6c0328061 Author: Joost Kremers Commit: Joost Kremers New function `c2l-get-results-buffer`. --- csv2ledger.el | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 8cecb4d8f2..eff8f98f66 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -143,6 +143,7 @@ returns a match wins." (defvar c2l--accounts nil "List of ledger accounts, mainly used for completion.") (defvar c2l--compiled-matcher-regexes nil "Alist of accounts and their matchers.") +(defvar c2l--results-buffer nil "Buffer for conversion results.") (defun c2l-convert-little-endian-to-iso8601-date (date) "Convert DATE from a little-endian format to an ISO 8601 format. @@ -289,6 +290,20 @@ like a number." (fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row (not (string-match-p "[0-9]+[0-9.,]*[.,][0-9]\\{2\\}" (alist-get 'amount fields)) +(defun c2l-get-results-buffer () + "Create a results buffer for conversion. +The buffer is called \"*Csv2Ledger Results*\". If a buffer with +this name already exists, it is erased and returned. Otherwise a +new buffer is created." + (if (and c2l--results-buffer + (buffer-live-p c2l--results-buffer)) + (with-current-buffer c2l--results-buffer +(erase-buffer)) +(setq c2l--results-buffer (get-buffer-create "*Csv2Ledger Results*")) +(with-current-buffer c2l--results-buffer + (ledger-mode))) + c2l--results-buffer) + ;;;###autoload (defun c2l-set-base-account () "Set `c2l-base-account'." @@ -320,9 +335,7 @@ This function always returns nil. The converted entries are placed in the buffer \"*Csv2Ledger Results*\", which is erased beforehand if it already exists." (interactive "r") - (let ((buffer (get-buffer-create "*Csv2Ledger Results*"))) -(with-current-buffer buffer - (erase-buffer)) + (let ((buffer (c2l-get-results-buffer)) (save-mark-and-excursion (goto-char start) (beginning-of-line)
[nongnu] elpa/csv2ledger 7bf8eea86a 130/190: Update doc string of c2l-convert-buffer.
branch: elpa/csv2ledger commit 7bf8eea86a26ed6c017981162ad07ef20cf9d656 Author: Joost Kremers Commit: Joost Kremers Update doc string of c2l-convert-buffer. --- csv2ledger.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 67dc180921..d7e6c7b22c 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -493,9 +493,8 @@ beforehand if it already exists." "Convert the CSV entries in the current buffer to ledger entries. The converted entries are placed in the buffer \"*Csv2Ledger Results*\", which is erased beforehand if it already exists. If -the first line of the buffer is a header line, it is -skipped. (The first line is considered to be a header if no -amount can be found in the amount column.)" +the first line of the buffer looks like a header line (see +`c2l--has-header'), it is skipped." (interactive) (let ((beg (save-mark-and-excursion (goto-char (point-min))
[nongnu] elpa/csv2ledger c8939a4422 188/190: Fix c2l-read-account-matchers
branch: elpa/csv2ledger commit c8939a44220d39377a105debeeb9a4f54637a40e Author: Joost Kremers Commit: Joost Kremers Fix c2l-read-account-matchers - Add interactive spec. - Add a message to let the user know that the account matchers have been re-read. --- csv2ledger.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 475fda6944..a34efa2679 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -502,7 +502,9 @@ new buffer is created." (defun c2l-read-account-matchers () "(Re)read the account matchers file." - (c2l-set-matcher-regexps 'force)) + (interactive) + (c2l-set-matcher-regexps 'force) + (message "[Csv2Ledger] Reading account matchers file... Done.")) ;;;###autoload (defun c2l-csv-entry-as-kill ()
[nongnu] elpa/csv2ledger 144a966942 150/190: Add section on multiple configurations to the README
branch: elpa/csv2ledger commit 144a9669422ce3c609cca6c8cc59ad6a26efb526 Author: Joost Kremers Commit: Joost Kremers Add section on multiple configurations to the README --- README.md | 21 + 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 1c49e7c4c6..673e6544c6 100644 --- a/README.md +++ b/README.md @@ -235,3 +235,24 @@ After all modification functions have been called, the resulting transaction is The function `c2l-compose-entry` requires that at least the `date`, `title`, `amount` and `account` fields be present in the transaction. In addition, the fields `description` and `posted` are used if they are present. If you write your own custom function, that requirement no longer holds, of course. (In fact, there is not even a requirement that what the `c2l-entry-function` writes out is an actual ledger entry. You could have it convert CSV entries into JSON or YAML or whatever you like.) + +## Different banks, different CSV files ## + +If you have to deal with more than one bank, most likely the CSV files from those banks will be different and require different settings for the options discussed here. You can deal with this using directory-local variables. + +How to set up directory-local variables is discussed in the Emacs manual (see the Info node `(emacs) Directory Variables"`). As an example, you can create a `.dir-locals.el` file with the following content: + +``` +((csv-mode . ((c2l-accounts-file . "~/Finances/Accounts.ledger") + (c2l-account-matchers-file . "~/Finances/Account_matchers.tsv") + (c2l-base-account . "Assets:Checking") + (c2l-fallback-account . "Expenses:Faalback") + (c2l-csv-columns . (date _ type description payee amount _)) + (c2l-auto-cleared . t +``` + +This will apply all listed `c2l` settings to all CSV files in the directory in containing the `.dir-locals.el` file. As long as you keep the CSV files from the two banks in different directories, you can use this strategy to set them up differently. + +If you prefer to keep your `csv2ledger` configuration in your init file, you can use the functions `dir-locals-set-directory-class` and `dir-locals-set-class-variables` to set up directory-local variables for specific directories. The Info node mentioned above explains how to do this. + +One (small) disadvantage of this approach is that some of the customisation options are considered unsafe or risky by Emacs, so when you open a CSV file, Emacs will ask you if you want to apply them. If you tell Emacs to apply them and set them as safe for future use, you'll only see that question once for a directory, however.
[nongnu] elpa/csv2ledger f299813350 146/190: Recognise amounts without cents in c2l--amount-p
branch: elpa/csv2ledger commit f299813350ff94cf89d7600ec9aaf7b9fe6ec2cc Author: Joost Kremers Commit: Joost Kremers Recognise amounts without cents in c2l--amount-p --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index eb06558c62..0999355a95 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -347,7 +347,7 @@ Return the modified transaction." (defun c2l--amount-p (str) "Return non-nil is STR is likely to be an amount." - (if (string-match-p "[0-9]+[0-9.,]*[.,][0-9]\\{2\\}" str) + (if (string-match-p "[0-9]+[0-9.,]*\\(?:[.,][0-9]\\{2\\}\\)?" str) str)) (defun c2l-compose-entry (transaction)
[nongnu] elpa/csv2ledger 4bd99b140a 164/190: Make sure all relevant variables become buffer-local when needed.
branch: elpa/csv2ledger commit 4bd99b140aea5ecb2cbc36826f15039f47afd3c1 Author: Joost Kremers Commit: Joost Kremers Make sure all relevant variables become buffer-local when needed. Specifically, c2l-transaction-modifier, c2l-matcher-regexps and c2l–accounts need to be buffer-local. Of these, c2l-matcher-regexps must also be able to have a default value. --- csv2ledger.el | 92 +-- 1 file changed, 39 insertions(+), 53 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 24236c9c98..22caca04da 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -150,38 +150,32 @@ for the field in question." :type '(repeat (cons (symbol :tag "Field") function)) :group 'csv2ledger) -(defvar c2l-transaction-modifier nil +(defcustom c2l-transaction-modify-functions '(c2l-create-title c2l-create-amount c2l-create-account) + "List of functions applied to the transaction before creating an entry. +The functions are applied in the order in which they appear in +the list. Each function should take an alist representing a +transaction as argument and should return the modified +transaction." + :type '(repeat function) + :safe (lambda (v) + (seq-every-p #'symbolp v)) + :group 'csv2ledger) + +(defvar-local c2l-transaction-modifier nil "The function that modifies a CSV transaction before creating a ledger entry. This is the composite function created with the functions in `c2l-transaction-modify-functions'.") -(defun c2l-compose-transaction-modifier (fns) +(defun c2l-compose-transaction-modifier () "Function to set the variable `c2l-transaction-modifier'. FNS is a list of functions, which is reversed and then composed into a single function taking a transaction alist as argument and returning a modified transaction alist." ;; Note: We need to reverse FNS, because `-compose' composes them from right ;; to left (i.e., the last function in FNS is applied first). - (setq c2l-transaction-modifier (apply #'-compose (reverse fns - -(defcustom c2l-transaction-modify-functions '(c2l-create-title c2l-create-amount c2l-create-account) - "List of functions applied to the transaction before creating an entry. -The functions are applied in the order in which they appear in -the list. Each function should take an alist representing a -transaction as argument and should return the modified -transaction. + (or c2l-transaction-modifier + (setq c2l-transaction-modifier (apply #'-compose (reverse c2l-transaction-modify-functions) -These functions are composed into a single function which is then -stored in the variable `c2l-transaction-modifier'. If you set -this option outside of Customize, make sure to call the function -`c2l-compose-transaction-modifier' as well." - :type '(repeat function) - :set (lambda (var val) - (c2l-compose-transaction-modifier val) - (set-default var val)) - :safe (lambda (v) - (seq-every-p #'symbolp v)) - :group 'csv2ledger) (defcustom c2l-entry-function #'c2l-compose-entry "Function to create a ledger entry. @@ -220,26 +214,6 @@ See the documentation for the variable 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 ( . ) conses, where - should be unique but 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 @@ -254,19 +228,31 @@ 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. - -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'." +book the transaction." :type 'file - :set (lambda (sym val) - (set sym val) - (c2l-set-matcher-regexps val)) :safe #'stringp :group 'csv2ledger) +(defun c2l--compile-matcher-regexps (accounts) + "Create efficient regular expressio
[nongnu] elpa/csv2ledger af1129653d 178/190: Make auto-clearing of transactions with effective date optional.
branch: elpa/csv2ledger commit af1129653d30c8bba180633d506dbc184d2b28bd Author: Joost Kremers Commit: Joost Kremers Make auto-clearing of transactions with effective date optional. Add new value to user option c2l-auto-cleared: if set to `if-posted`, transactions with an effective date are cleared. If `nil`, transactions are never auto-cleared, even when they have an effective date. If `t`, transactions are always auto-cleared. --- README.md | 2 +- csv2ledger.el | 29 +++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 827404ad1a..b5db2cc691 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Not indicated in the above example is the *effective* date (also called *posted* Assets:Checking -€25.10 ``` -If you have this information in your CSV file, you can use it and add it to the entry. If such an effective date is found, the entry is also marked as cleared, i.e., an asterisk appears between the date and the title. +If you have this information in your CSV file, you can use it and add it to the entry. ## Installation ## diff --git a/csv2ledger.el b/csv2ledger.el index 03a753a979..2110acee2f 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -265,10 +265,11 @@ returns a match is used as the target account." :group 'csv2ledger) (defcustom c2l-auto-cleared nil - "If non-nil, mark every entry as cleared. -This puts an asterisk between the date and the payee." - :type 'boolean - :safe #'booleanp + "If non-nil, mark every transaction as cleared." + :type '(choice (const :tag "Never auto-clear transactions" nil) + (const :tag "Always auto-clear transactions" t) + (const :tag "Auto-clear if effective date is present" if-posted)) + :safe #'symbolp :group 'csv2ledger) (defcustom c2l-alignment-column 52 @@ -392,17 +393,17 @@ be included in the entry. It should at least contain values for the keys `date', `title', `amount' and `account'. TRANSACTION may also contain a value for `posted' and `description'. If `posted' is present, it is added as the effective date for the -entry and the entry is marked as cleared. If `description' is -present, it is added as a comment, preceded by \"Desc:\". If -`c2l-auto-cleared' is non-nil, the entry is always marked as -cleared, even if there is no value for `posted' in TRANSACTION." +entry. If `description' is present, it is added as a comment, +preceded by \"Desc:\". If `c2l-auto-cleared' is non-nil, the +entry is marked as cleared." (let-alist transaction -(concat .date (if .posted (format "=%s " .posted) "") (if (or .posted c2l-auto-cleared) " *" "") " " .title "\n" -(if (and .description (not (string-empty-p .description))) (format "; Desc: %s\n" .description) "") -(format "%s\n" .account) -(format "%s " c2l-base-account) -(make-string (- c2l-alignment-column 4 (length c2l-base-account) 2 (length .amount)) ?\s) -.amount "\n"))) +(let ((cleared (if (eq c2l-auto-cleared 'if-posted) .posted c2l-auto-cleared))) + (concat .date (if .posted (format "=%s" .posted) "") (if cleared " * " " ") .title "\n" + (if (and .description (not (string-empty-p .description))) (format "; Desc: %s\n" .description) "") + (format "%s\n" .account) + (format "%s " c2l-base-account) + (make-string (- c2l-alignment-column 4 (length c2l-base-account) 2 (length .amount)) ?\s) + .amount "\n" ;;; Helper functions
[nongnu] elpa/csv2ledger e0be339259 068/190: Add function c2l-title-is-counterpart.
branch: elpa/csv2ledger commit e0be3392596d67eb54608ee9e6e2dc50a319a5f7 Author: Joost Kremers Commit: Joost Kremers Add function c2l-title-is-counterpart. This function is a possible value for c2l-title-function. --- csv2ledger.el | 11 +++ 1 file changed, 11 insertions(+) diff --git a/csv2ledger.el b/csv2ledger.el index 3a7fa4d4d3..62b6ea7d5e 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -209,7 +209,18 @@ otherwise the payee is returned." payee) payee))) +<<< HEAD (defun c2l--compose-entry (items &optional from to) +=== +(defun c2l-title-is-counterpart (transaction) + "Return the counterpart of an entry. +This function is for use as the value of `c2l-title-function'. +TRANSACTION should be an alist containing field-value pairs and +should contain a value for `counterpart', which is the return +value. If `counterpart' does not have a value, this function +returns \"Unknown\"." + (alist-get 'counterpart transaction "Unknown")) +>>> Add function c2l-title-is-counterpart. "Create a ledger entry. ITEMS is an alist containing (key . value) pairs that should be included in the entry. It should contain values for the keys
[nongnu] elpa/csv2ledger 0af0aa3de2 021/190: Rename `c2l-parse-date` and update doc string.
branch: elpa/csv2ledger commit 0af0aa3de218ce82bc74ea178578ab912e78f657 Author: Joost Kremers Commit: Joost Kremers Rename `c2l-parse-date` and update doc string. New name: `c2l-convert-little-endian-to-iso8601-date`. It's a mouth full, but it better represents the function's purpose. --- csv2ledger.el | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 61db9288ec..8368036bb0 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -139,9 +139,6 @@ returns a match wins." :type '(repeat symbol) :group 'csv2ledger) -(defun c2l-parse-date (date) - "Convert DATE from \"17.10.2022\" to \"2022-10-17\"." - (string-join (nreverse (split-string date "\\.")) "-")) (defcustom c2l-auto-reconcile nil "If non-nil, mark every entry as reconciled." :type 'boolean @@ -149,6 +146,18 @@ returns a match wins." (defun c2l-compose-entry (date title amount &optional description from to) +(defun c2l-convert-little-endian-to-iso8601-date (date) + "Convert DATE from a little-endian format to an ISO 8601 format. +DATE should be a string representing a date of the form +DD.MM.. Return value is a date string of the form -MM-DD. + +Note that the input date may have dots, dashes or forward slashes +separating the date parts; also, additional whitespace is +removed. This function does not check if DATE has a valid date +format, it just splits DATE on the separator, reverses the date +parts and joins them again." + (string-join (nreverse (split-string date "[./-]" t "[[:space:]]")) "-")) + "Create a ledger entry. DATE, TITLE, AMOUNT are used to create the entry. DESCRIPTION, if non-nil, is added as a comment, preceded by \"Desc:\". FROM
[nongnu] elpa/csv2ledger d5718b1875 046/190: Add dependencies to package header.
branch: elpa/csv2ledger commit d5718b18755f44e05b107fbca87930b8428f49ee Author: Joost Kremers Commit: Joost Kremers Add dependencies to package header. --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index bbe743c415..53ab20e54a 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -7,7 +7,7 @@ ;; Maintainer: Joost Kremers ;; Created: 2022 ;; Version: 1.0 -;; Package-Requires: ((emacs "28.1")) +;; Package-Requires: ((emacs "28.1") (ledger-mode) (parse-csv) (dash "2.19.1")) ;; This file is NOT part of GNU Emacs.
[nongnu] elpa/csv2ledger 3084bc9a64 125/190: Update the README.
branch: elpa/csv2ledger commit 3084bc9a6433252f046cb80739f2a3402d5c15d5 Author: Joost Kremers Commit: Joost Kremers Update the README. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9ec823d3ee..26f8abc0a7 100644 --- a/README.md +++ b/README.md @@ -110,16 +110,16 @@ restaurantExpenses:Leisure:Restaurant Set the option `c2l-account-matchers-file` to point to this file. With the example matchers shown here, if the payee or description (or any other field you configure) of a transaction contains the string `"aldi"`, `Expenses:Groceries` is taken as the balancing account. There can be more than one matcher for one account: in the example, both `"aldi"` and `"lidl"` link to the account `Expenses:Groceries`. -The matchers are simple substrings, not regular expressions. I have not found the need to use regular expressions for account matching, and prefer the simplicity of not having to worry about the special meaning of certain characters in them. Internally, however, the matchers are turned into regular expressions and stored in the variable `c2l-account-regexps`. If you prefer to use regular expressions, you can set this variable yourself. Its value should be an alist mapping regular express [...] +The matchers are simple substrings, not regular expressions. I have not found the need to use regular expressions for account matching, and prefer the simplicity of not having to worry about the special meaning of certain characters in them. Internally, however, the matchers are turned into regular expressions and stored in the variable `c2l-matcher-regexps`. If you prefer to use regular expressions, you can set this variable yourself. Its value should be an alist mapping regular express [...] ``` (("\\(?:aldi\\|lidl\\)" . "Expenses:Groceries") ("\\(?:restaurant\\)" . "Expenses:Leasure:Restaurant")) ``` -`c2l-account-regexps` is not a customisable option. If you set it to a value yourself though, `csv2ledger` will not overwrite it (and ignore the value of `c2l-account-matchers-file`). Just make sure that the value is set before calling any functions from `csv2ledger` (but after loading the library), and keep in mind that if you have multiple regexps matching a transaction, the first regex that matches wins out. +`c2l-matcher-regexps` is not a customisable option. If you set it to a value yourself though, `csv2ledger` will not overwrite it (and ignore the value of `c2l-account-matchers-file`). Just make sure that the value is set before calling any functions from `csv2ledger` (but after loading the library), and keep in mind that if you have multiple regexps matching a transaction, the first regex that matches wins out. -Matching an account specifically means matching the values of the fields listed in `c2l-target-match-fields` against the regexps in `c2l-account-regexps`. The first regexp that matches wins. By default, `c2l-target-match-fields` only contains the `payee` and `description` fields, but you can add other fields to it as well. (In fact, I set it to the value `(description payee sender type)`.) +Matching an account specifically means matching the values of the fields listed in `c2l-target-match-fields` against the regexps in `c2l-matcher-regexps`. The first regexp that matches wins. By default, `c2l-target-match-fields` only contains the `payee` and `description` fields, but you can add other fields to it as well. (In fact, I set it to the value `(description payee sender type)`.) Two things are of note here: first, the order of this list determines the order in which the fields get checked. The default value is `(payee description)`, so the `payee` field is checked before `description`. I prefer for the `description` field to be checked first, because it tends to contain more information than the `payee` field, so in my setup, I put `description` first. Second, I added the `type` field to the list. As already mentioned, `csv2ledger` does not do anything with this [...]
[nongnu] elpa/csv2ledger 4d888caef4 187/190: Fix whitespace.
branch: elpa/csv2ledger commit 4d888caef4b1314536dcc56cda2354dbbad2a490 Author: Joost Kremers Commit: Joost Kremers Fix whitespace. --- csv2ledger.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 1166ca88ff..475fda6944 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -323,8 +323,8 @@ Return the modified transaction." "Create the amount for TRANSACTION. Return the modified transaction." (unless (c2l--amount-p (alist-get 'amount transaction "")) -(let ((amount (or (c2l--amount-p (alist-get 'credit transaction "")) - (c2l--amount-p (alist-get 'debit transaction "")) +(let ((amount (or (c2l--amount-p (alist-get 'credit transaction "")) + (c2l--amount-p (alist-get 'debit transaction "")) "0.00"))) (if (alist-get 'amount transaction) (setf (alist-get 'amount transaction) amount)
[nongnu] elpa/csv2ledger 2bcc1a8e76 175/190: Improve doc string of c2l-create-account
branch: elpa/csv2ledger commit 2bcc1a8e76ee54dfd71fb54a469b9a9f1fce1754 Author: Joost Kremers Commit: Joost Kremers Improve doc string of c2l-create-account --- csv2ledger.el | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 4914ba9426..3cdda3224f 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -328,7 +328,10 @@ Return the modified transaction." transaction) (defun c2l-create-account (transaction) - "Create the account for TRANSACTION." + "Get the balancing account for TRANSACTION. +First check if the account matchers provide a balancing account. +If not, use `c2l-fallback-account' if provided. If neither +method yields an account, ask the user." (let ((account (or (seq-some #'c2l--match-account (mapcar #'cdr (seq-filter (lambda (e) (memq (car e) c2l-target-match-fields))
[nongnu] elpa/csv2ledger 57bd4d12f2 160/190: Move definition of c2l-field-modify-functions.
branch: elpa/csv2ledger commit 57bd4d12f25de447a1d652b87bda5b5f216ad73e Author: Joost Kremers Commit: Joost Kremers Move definition of c2l-field-modify-functions. The functions in c2l-field-modify-functions are applied before c2l-transaction-modify-functions, so it makes sense to have it first. (This is mainly true in the README, but the order of customise options in the README reflects the order of the defcustoms in the source code.) --- csv2ledger.el | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index adb7f555ef..24236c9c98 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -141,6 +141,15 @@ in the transaction. They may be used in the option :type '(repeat symbol) :group 'csv2ledger) +(defcustom c2l-field-modify-functions nil + "List of functions to modify fields in an entry. +This option should be an alist mapping field names (as symbols) +to functions. These functions should take a single string +argument and should return a string, which will be the value used +for the field in question." + :type '(repeat (cons (symbol :tag "Field") function)) + :group 'csv2ledger) + (defvar c2l-transaction-modifier nil "The function that modifies a CSV transaction before creating a ledger entry. This is the composite function created with the functions in @@ -174,15 +183,6 @@ this option outside of Customize, make sure to call the function (seq-every-p #'symbolp v)) :group 'csv2ledger) -(defcustom c2l-field-modify-functions nil - "List of functions to modify fields in an entry. -This option should be an alist mapping field names (as symbols) -to functions. These functions should take a single string -argument and should return a string, which will be the value used -for the field in question." - :type '(repeat (cons (symbol :tag "Field") function)) - :group 'csv2ledger) - (defcustom c2l-entry-function #'c2l-compose-entry "Function to create a ledger entry. This should be a function that takes an alist of field-value
[nongnu] elpa/csv2ledger 02a6ebc5b3 019/190: Add user option `c2l-auto-reconcile`.
branch: elpa/csv2ledger commit 02a6ebc5b3257edee1f7e0bca14aafc22c5dd2a9 Author: Joost Kremers Commit: Joost Kremers Add user option `c2l-auto-reconcile`. --- csv2ledger.el | 4 1 file changed, 4 insertions(+) diff --git a/csv2ledger.el b/csv2ledger.el index a19fa50826..70451ed897 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -142,6 +142,10 @@ returns a match wins." (defun c2l-parse-date (date) "Convert DATE from \"17.10.2022\" to \"2022-10-17\"." (string-join (nreverse (split-string date "\\.")) "-")) +(defcustom c2l-auto-reconcile nil + "If non-nil, mark every entry as reconciled." + :type 'boolean + :group 'csv2ledger) (defun c2l-parse-amount (amount) "Convert AMOUNT from \"-3.150,20 €\" to \"-€3150.20\"."
[nongnu] elpa/csv2ledger 22c9d76302 136/190: Fix doc string of c2l-transaction-modify-functions.
branch: elpa/csv2ledger commit 22c9d7630245b38b5818aafdbaa2f52abecb25ec Author: Joost Kremers Commit: Joost Kremers Fix doc string of c2l-transaction-modify-functions. --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 58bab91029..88d720e66a 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -158,7 +158,7 @@ transaction. These functions are composed into a single function which is then stored in the variable `c2l-transaction-modifier'. If you set this option outside of Customize, make sure to call the function -`c2l-set-transaction-modifier ' as well." +`c2l-compose-transaction-modifier' as well." :type '(repeat function) :set (lambda (var val) (c2l-compose-transaction-modifier val)
[nongnu] elpa/csv2ledger 61f3d6d75f 158/190: Update Commentary section.
branch: elpa/csv2ledger commit 61f3d6d75fdad78d2b2d1bf1a44a3b713382a9c7 Author: Joost Kremers Commit: Joost Kremers Update Commentary section. --- csv2ledger.el | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index d5dc4918a9..adb7f555ef 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -48,11 +48,11 @@ ;; for each transaction for which `csv2ledger' could not find one and instead ;; prefer to correct the resulting ledger entries afterwards. ;; -;; Normally, a ledger entry has the payee at the top of an entry, but if you -;; receive money, your CSV file may list you as the payee. To use the sender -;; instead in such cases, set the variable `c2l-account-holder' to a regular -;; expression matching your name (i.e., whatever appears as the payee in your -;; CSV file when you receive money). +;; Normally, a ledger entry starts with a date and the payee, but if you receive +;; money, your CSV file may list you as the payee. To use the sender instead in +;; such cases, set the variable `c2l-account-holder' to a regular expression +;; matching your name (i.e., whatever appears as the payee in your CSV file when +;; you receive money). ;; ;; If you need to make any kind of changes to the data in your CSV file or wish ;; to customise the format of your ledger entries, look at the variables
[nongnu] elpa/csv2ledger a9bc221c12 051/190: Require subr-x for string functions.
branch: elpa/csv2ledger commit a9bc221c12332b8c199555adf1314db01fbf5bc1 Author: Joost Kremers Commit: Joost Kremers Require subr-x for string functions. The byte compiler complains about `string-join` and `string-empty-p`. --- csv2ledger.el | 1 + 1 file changed, 1 insertion(+) diff --git a/csv2ledger.el b/csv2ledger.el index 14daf842cf..f380938149 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -31,6 +31,7 @@ ;;; Code: (require 'ledger-mode) +(require 'subr-x) (require 'parse-csv) (require 'csv-mode) (require 'dash)
[nongnu] elpa/csv2ledger 88c394d5bb 066/190: Rename c2l-payee-or-sender to c2l-title-is-payee-or-sender.
branch: elpa/csv2ledger commit 88c394d5bbe28b5ef8f550e459dab4f528f65535 Author: Joost Kremers Commit: Joost Kremers Rename c2l-payee-or-sender to c2l-title-is-payee-or-sender. --- csv2ledger.el | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 0bacacb017..be15f59463 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -120,7 +120,7 @@ for the field in question." :type '(repeat (cons (symbol :tag "Field") function)) :group 'csv2ledger) -(defcustom c2l-title-function #'c2l-payee-or-sender +(defcustom c2l-title-function #'c2l-title-is-payee-or-sender "Function to create a title. The function should take as argument an entry alist of field-value pairs and should return a string. The string @@ -194,21 +194,22 @@ format, it just splits DATE on the separator, reverses the date parts and joins them again, using a hyphen as separator." (string-join (nreverse (split-string date "[./-]" t "[[:space:]]")) "-")) -(defun c2l-payee-or-sender (entry) +(defun c2l-title-is-payee-or-sender (transaction) "Return payee or sender based on `c2l-account-holder'. This function is for use as the value of `c2l-title-function'. -ENTRY should be an alist containing field-value pairs for an -entry and should contain values for `payee' and `sender'. If the -value of `c2l-account-holder' matches the payee, the sender is -returned, otherwise the payee is returned." - (when (stringp c2l-account-holder) -(let ((payee (alist-get 'payee entry)) - (sender (alist-get 'sender entry))) - (if (string-match-p c2l-account-holder payee) - sender -payee (defun c2l--compose-entry (items &optional from to) +TRANSACTION should be an alist containing field-value pairs and +should contain values for `payee' and `sender'. If the value of +`c2l-account-holder' matches the payee, the sender is returned, +otherwise the payee is returned." + (let ((payee (alist-get 'payee transaction)) +(sender (alist-get 'sender transaction))) +(if (stringp c2l-account-holder) +(if (string-match-p c2l-account-holder payee) +sender + payee) + payee))) "Create a ledger entry. ITEMS is an alist containing (key . value) pairs that should be included in the entry. It should contain values for the keys
[nongnu] elpa/csv2ledger 4f7505922c 037/190: Update regex in `c2l-has-header`.
branch: elpa/csv2ledger commit 4f7505922c0daac19411544c1a332d64b184768b Author: Joost Kremers Commit: Joost Kremers Update regex in `c2l-has-header`. --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index b7583574b0..4dae11020b 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -287,7 +287,7 @@ like a number." (goto-char (point-min)) (let* ((row (c2l-get-current-row)) (fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row - (not (string-match-p "[0-9,.-]+" (alist-get 'amount fields)) + (not (string-match-p "[0-9]+[0-9.,]*[.,][0-9]\\{2\\}" (alist-get 'amount fields)) ;;;###autoload (defun c2l-set-base-account ()
[nongnu] branch elpa/csv2ledger created (now 91a9c504a7)
elpasync pushed a change to branch elpa/csv2ledger. at 91a9c504a7 Update version number This branch includes the following new commits: new 95595c0d79 Initial commit new b4f6fac379 Add .gitignore new 6597b8cd22 Initial commit of csv2ledger.el new e8a2151fc7 Fix references to `jk--ledger-compiled-account-regexes`. new 1ce1fe5297 Remove BSD license from header, point to GNU license. new d8ee57f181 Update copyright year. new 7635ee6fe3 Update "Created" year in header. new 09f023793a Declare Emacs 28.1 as a dependency. new 73ef91df00 Turn variables into user options or internal variables. new cc83ffef1c Rename `c2l-compile-account-regexes` to `c2l-compile-matcher-regexes`. new 0326110f7a Update doc string of `c2l-read-account-matchers`. new 6023fa373b Use lower-case column names in `c2l-csv-columns`. new c1fb4a3255 Reconcile commits 6023fa3 and 1e4bd7c. new aa435296c8 Update doc string of `c2l-csv-columns`. new c7d1db033c Add user option `c2l-field-parse-functions`. new 97906fa4ce Add user option `c2l-title-function`. new 900eef1457 Move definition of `c2l-account-matchers-file`. new 5dd5e36a07 Add user option `c2l-title-match-fields`. new 02a6ebc5b3 Add user option `c2l-auto-reconcile`. new 2cf9b08114 Remove function `c2l-parse-amount`. new 0af0aa3de2 Rename `c2l-parse-date` and update doc string. new 7932657f9f Move definitions of internal variables after defcustoms. new 6e9838193e New function: `c2l-payee-or-sender`. new c5b7b0766e Rewrite `c2l-compose-entry` and `c2l-csv-line-to-ledger`. new 3ed3afc06b Update doc string of `c2l-csv-entry-as-kill`. new 8e01e8379b Update doc string of `c2l-base-account`. new c01946ab58 Do not try to read files that do not exist. new eaf2ad4fee Do not test if file exists if file is nil. new 7cc0cd1a0a Warn if trying to read a file that cannot be found. new fd54efa6ce Add command `c2l-set-base-account`. new be1366e6d4 c2l-payee-or-sender: first check if `c2l-account-holder` is even set. new 579acc2d00 Do not require a match when asking for an account name. new a7b24edc4d Start README.md new 466a098d2b Extract new function `c2l-get-current-row` from `c2l-csv-entry-as-kill`. new 799beb345b New function `c2l-has-header`. new 09e02e84a5 Expand README.md new 4f7505922c Update regex in `c2l-has-header`. new a0a328df02 New function `c2l-convert-region`. new 671fef23b4 Small refactor of `c2l-csv-entry-as-kill`. new f536bca1bf New function `c2l-get-results-buffer`. new 93bd85b0e0 c2l-convert-region: Report number of converted entries. new 7c84259a9d Update error messages with "[Csv2Ledger]" tag. new 393b9d9688 New function: c2l-convert-buffer. new d00914d9f1 c2l-csv-line-to-ledger: Check c2l-fallback-account before asking the user. new b5a85b4589 Remove defvar declaration for ledger-post-amount-alignment-column. new d5718b1875 Add dependencies to package header. new 463fa78c33 Rename internal functions with double dash. new 6f65342c60 Update the README. new 19b3176424 Add flycheck temp files to .gitignore. new e8a7609736 Add user option `c2l-alignment-column`. new a9bc221c12 Require subr-x for string functions. new 482658ee03 Remove dependency on ledger-mode. new a1b0dd35e1 Update README. new 3694ef7269 Small updates to the README. new 20f06b3d99 Rename `c2l-auto-reconciled`to `c2l-auto-cleared`. new 03b2aeb4a7 Update the README. new 188ddacde7 Rename target account to balancing account. new aaf8db1085 Make c2l-matcher-regexes public. new 40e1230600 Fix doc string of `c2l--csv-line-to-ledger`. new ae252fe149 Rename c2l-fallback-balancing-account back to c2l-fallback-account. new 05b1225a0b Fix alignment. new 0d3a88f8bc Rename `valuation` field to `effective`. new 3e07f6edbe Update doc string of `c2l-csv-columns`. new 9dd9708b94 Rename `c2l-field-parse-functions` to `c2l-field-modify-functions` new 6f417351a8 Update doc string of c2l-convert-little-endian-to-iso8601-date. new 88c394d5bb Rename c2l-payee-or-sender to c2l-title-is-payee-or-sender. new 9426c2a2d9 Rename c2l-payee-or-sender to c2l-title-is-payee-or-sender. new e0be339259 Add function c2l-title-is-counterpart. new 89a311301c New user option c2l-amount-function. new 565e1a1c43 Add comment line denoting section for user option functions. new e4a823e552 Add helper function c2l--amount-p. new 81322ebde0 Use c2l--amount-p in c2l--has-header. new 8dcb1e208f Rework c2l--compose-entry and c2l--csv-line-to-ledger new ea515e3ae6 Se
[nongnu] elpa/csv2ledger 05b1225a0b 061/190: Fix alignment.
branch: elpa/csv2ledger commit 05b1225a0bd69d1d8edfaa021ceda00910e618f0 Author: Joost Kremers Commit: Joost Kremers Fix alignment. --- csv2ledger.el | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 1057e4a3fc..3919f112cf 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -182,10 +182,10 @@ value of `c2l-account-holder' matches the payee, the sender is returned, otherwise the payee is returned." (when (stringp c2l-account-holder) (let ((payee (alist-get 'payee entry)) - (sender (alist-get 'sender entry))) - (if (string-match-p c2l-account-holder payee) - sender - payee + (sender (alist-get 'sender entry))) + (if (string-match-p c2l-account-holder payee) + sender +payee (defun c2l--compose-entry (items &optional from to) "Create a ledger entry.
[nongnu] elpa/csv2ledger d1910389f1 100/190: Rename c2l-title-is-payee-or-sender to c2l-payee-or-sender.
branch: elpa/csv2ledger commit d1910389f1156fba96bd4b1a01daf16966da6cf0 Author: Joost Kremers Commit: Joost Kremers Rename c2l-title-is-payee-or-sender to c2l-payee-or-sender. Since c2l-title-is-counterpart is now gone, the longer title seems a too much. --- csv2ledger.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 997ca69a41..00f154b950 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -140,7 +140,7 @@ for the field in question." :type '(repeat (cons (symbol :tag "Field") function)) :group 'csv2ledger) -(defcustom c2l-title-function #'c2l-title-is-payee-or-sender +(defcustom c2l-title-function #'c2l-payee-or-sender "Function to create a title. The function should take as argument an entry alist of field-value pairs and should return a string. The string @@ -237,7 +237,7 @@ format, it just splits DATE on the separator, reverses the date parts and joins them again, using a hyphen as separator." (string-join (nreverse (split-string date "[./-]" t "[[:space:]]")) "-")) -(defun c2l-title-is-payee-or-sender (transaction) +(defun c2l-payee-or-sender (transaction) "Return payee or sender based on `c2l-account-holder'. This function is for use as the value of `c2l-title-function'. TRANSACTION should be an alist containing field-value pairs and
[nongnu] elpa/csv2ledger 18413f1c36 076/190: Fix typo in doc string of c2l-matcher-regexes.
branch: elpa/csv2ledger commit 18413f1c36cde82e8fadf00f66a9580bd6c39dad Author: Joost Kremers Commit: Joost Kremers Fix typo in doc string of c2l-matcher-regexes. --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index c18ab7d78e..af73cf9db6 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -163,7 +163,7 @@ used as the balancing 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 regexes to match account.") +you prefer to use regexes to match accounts.") (defcustom c2l-balancing-match-fields '(payee description) "List of fields used for determining the balancing account.
[nongnu] elpa/csv2ledger 81322ebde0 072/190: Use c2l--amount-p in c2l--has-header.
branch: elpa/csv2ledger commit 81322ebde0b494bc42d84de03acf62cfe51a5b6b Author: Joost Kremers Commit: Joost Kremers Use c2l--amount-p in c2l--has-header. --- csv2ledger.el | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index b007b4b450..1b952fa40a 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -373,14 +373,16 @@ Return value is a list of values as strings." (defun c2l--has-header () "Return non-nil if the current CSV buffer appears to have a header. -Essentially, this function just takes the field that should -contain the amount and checks if it contains something that looks -like a number." +Essentially, this function just checks the fields `amount', +`credit' and `debit' and returns non-nil if either one of these +contains something that looks like a amount." (save-mark-and-excursion (goto-char (point-min)) (let* ((row (c2l--get-current-row)) (fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row - (not (string-match-p "[0-9]+[0-9.,]*[.,][0-9]\\{2\\}" (alist-get 'amount fields)) + (not (or (c2l--amount-p (alist-get 'amount fields "")) + (c2l--amount-p (alist-get 'credit fields "")) + (c2l--amount-p (alist-get 'debit fields ""))) (defun c2l--get-results-buffer () "Create a results buffer for conversion.
[nongnu] elpa/csv2ledger 1d1004507c: Fix Package-Requires header.
branch: elpa/csv2ledger commit 1d1004507c4973b35f54d3b7207ee0477e067ba3 Author: Joost Kremers Commit: Joost Kremers Fix Package-Requires header. Also update version number. --- csv2ledger.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index c5470d6933..8820b2eee1 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -6,8 +6,8 @@ ;; Author: Joost Kremers ;; Maintainer: Joost Kremers ;; Created: 2022 -;; Version: 1.5.1 -;; Package-Requires: ((emacs "29.1") ((csv-mode "1.24"))) +;; Version: 1.5.2 +;; Package-Requires: ((emacs "29.1") (csv-mode "1.24")) ;; URL: https://codeberg.org/joostkremers/csv2ledger ;; This file is NOT part of GNU Emacs.
[nongnu] elpa/csv2ledger bf995e11cb 080/190: Rename balancing account back to target account.
branch: elpa/csv2ledger commit bf995e11cb4d4a6f8233bafd0a60528ce393345d Author: Joost Kremers Commit: Joost Kremers Rename balancing account back to target account. 'Balancing account' may be more accurate, but it's too long for my taste. --- csv2ledger.el | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 9d271dce7c..48354f50a2 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -63,9 +63,9 @@ files are processed." :local t) (defcustom c2l-fallback-account nil - "Fallback for the balancing account in transactions. + "Fallback for the target or balancing account in transactions. When creating a ledger entry, csv2ledger tries to determine the -balancing account for the transaction based on the matchers in +target account for the transaction based on the matchers in `c2l-account-matchers-file'. If no acccount is found, the value of this variable is used. If the value is unset, the user is asked for an account." @@ -104,8 +104,8 @@ Valid column names are the following: Other column names can be added, but they cannot be used directly in the transaction. They may be used in the option -`c2l-balancing-match-fields' or in custom functions for the -options `c2l-title-function' and `c2l-amount-function', however. +`c2l-target-match-fields' or in custom functions for the options +`c2l-title-function' and `c2l-amount-function', however. It is assumed that a CSV file contains either `payee' and `sender' columns or a `counterpart' column, but not both, and @@ -172,8 +172,8 @@ 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-balancing-match-fields', the corresponding account is used -to book the transaction." +`c2l-target-match-fields', the corresponding account is used to +book the transaction." :type 'file :group 'csv2ledger) @@ -181,19 +181,19 @@ to book the transaction." "Alist of matcher regexes 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-balancing-match-fields', its corresponding account -is used as the balancing account. +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 regexes to match accounts.") -(defcustom c2l-balancing-match-fields '(payee description) - "List of fields used for determining the balancing account. +(defcustom c2l-target-match-fields '(payee description) + "List of fields used for determining the target account. Fields in this list are matched against the matchers in `c2l-account-matchers-file'. Note that the order of the fields in this list can be relevant, because the first field that -returns a match wins." +returns a match is used as the target account." :type '(repeat symbol) :group 'csv2ledger) @@ -363,10 +363,10 @@ for that account." ROW contains the data of the entry as a list of strings. The strings are interpreted according to the template in `c2l-csv-columns'. The transaction is booked to the account in -`c2l-base-account'. The balancing account is determined on the +`c2l-base-account'. The target account is determined on the basis of the matchers in `c2l-account-matchers-file'. If none is -found, the value of `c2l-fallback-account' is used. If -that option is unset, the user is asked for an account." +found, the value of `c2l-fallback-account' is used. If that +option is unset, the user is asked for an account." (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) (parsed-fields (mapcar (lambda (item) (let ((field (car item)) @@ -376,7 +376,7 @@ that option is unset, the user is asked for an account." fields)) (title (funcall c2l-title-function parsed-fields)) (amount (funcall c2l-amount-function parsed-fields)) - (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-balancing-match-fields) parsed-fields))) + (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-target-match-fields) parsed-fields))) c2l-fallback-account (completing-read (format "Account for transaction %s, %s «%.75s» " (funcall c2l-title-function parsed-fields)
[nongnu] elpa/xah-fly-keys 1e21829412 2/3: Merge pull request #168 from Necryotiks/master
branch: elpa/xah-fly-keys commit 1e2182941227383aa23eada25b9ecbb9f743fe99 Merge: 470c612021 5a9b243915 Author: Xah Lee Commit: GitHub Merge pull request #168 from Necryotiks/master Add QGMLWB from Carpalx --- xah-fly-keys.el | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/xah-fly-keys.el b/xah-fly-keys.el index 2216354864..d80b75a06a 100644 --- a/xah-fly-keys.el +++ b/xah-fly-keys.el @@ -1,4 +1,4 @@ -;;; xah-fly-keys.el --- ergonomic modal keybinding minor mode. -*- coding: utf-8; lexical-binding: t; -*- +2;;; xah-fly-keys.el --- ergonomic modal keybinding minor mode. -*- coding: utf-8; lexical-binding: t; -*- ;; Copyright © 2013, 2024 by Xah Lee @@ -127,6 +127,7 @@ ;; programer-dvorak ;; pt-nativo (Brazil) ;; qfmlwy +;; qgmlwb ;; qwerty ;; qwerty-abnt (Brazil) ;; qwerty-no (Norwegian) @@ -3132,7 +3133,20 @@ Q F M L W Y U O B J { } | D S T N R I A E H : \" Z V G C X P K < > ? " xah-fly-layout-diagrams) + + (puthash "qgmlwb" " +~ ! @ # $ % ^ & * ( ) _ + +` 1 2 3 4 5 6 7 8 9 0 - = + +q g m l w b y u v ; [ ] \\ +d s t n r i a e o h ' +z x c f j k p , . / +Q G M L W B Y U V : { } | +D S T N R I A E O H \" +Z X C F J K P < > ? +" xah-fly-layout-diagrams) + (puthash "qwerty" " ~ ! @ # $ % ^ & * ( ) _ + ` 1 2 3 4 5 6 7 8 9 0 - =
[nongnu] elpa/csv2ledger 188ddacde7 057/190: Rename target account to balancing account.
branch: elpa/csv2ledger commit 188ddacde7a5b8eb3d1b8370e7bea56f563db69b Author: Joost Kremers Commit: Joost Kremers Rename target account to balancing account. --- csv2ledger.el | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 53e6003e50..4ce9a7960a 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -62,10 +62,10 @@ files are processed." :group 'csv2ledger :local t) -(defcustom c2l-fallback-account nil - "Fallback account for ledger transactions. +(defcustom c2l-fallback-balancing-account nil + "Fallback for the balancing account in transactions. When creating a ledger entry, csv2ledger tries to determine the -opposite account for the transaction based on the matchers in +balancing account for the transaction based on the matchers in `c2l-account-matchers-file'. If no acccount is found, the value of this variable is used. If the value is unset, the user is asked for an account." @@ -125,8 +125,8 @@ the corresponding account is used to book the transaction." :type 'file :group 'csv2ledger) -(defcustom c2l-title-match-fields '(payee description) - "List of fields used for matching the target account. +(defcustom c2l-balancing-match-fields '(payee description) + "List of fields used for determining the balancing account. Fields in this list are matched against the matchers in `c2l-account-matchers-file'. Note that the order of the fields in this list can be relevant, because the first field that @@ -187,9 +187,9 @@ comment, preceded by \"Desc:\". FROM is the account where the money comes from, TO the account to which it goes. Note that if AMOUNT is negative, these roles are -reversed. FROM and TO default to `c2l-fallback-account' and +reversed. FROM and TO default to `c2l-fallback-balancing-account' and `c2l-base-account', respectively." - (or from (setq from c2l-fallback-account)) + (or from (setq from c2l-fallback-balancing-account)) (or to (setq to c2l-base-account)) (let* ((parsed-items (mapcar (lambda (item) (let ((field (car item)) @@ -269,11 +269,11 @@ strings are interpreted according to the template in `c2l-csv-columns'. The transaction is booked to the account in `c2l-base-account'. The reverse account is determined on the basis of the matchers in `c2l-account-matchers-file'. If none is -found, the value of `c2l-fallback-account' is used. If that -option is unset, the user is asked for an account." +found, the value of `c2l-fallback-balancing-account' is used. If +that option is unset, the user is asked for an account." (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) - (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-title-match-fields) fields))) - c2l-fallback-account + (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-balancing-match-fields) fields))) + c2l-fallback-balancing-account (completing-read (format "Account for transaction %s, %s «%.75s» " (funcall c2l-title-function fields) (alist-get 'amount fields)
[nongnu] elpa/csv2ledger a0a328df02 038/190: New function `c2l-convert-region`.
branch: elpa/csv2ledger commit a0a328df02f0c7f7960cf5f7c470e111f2e36299 Author: Joost Kremers Commit: Joost Kremers New function `c2l-convert-region`. --- csv2ledger.el | 24 1 file changed, 24 insertions(+) diff --git a/csv2ledger.el b/csv2ledger.el index 4dae11020b..a040dbb826 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -309,6 +309,30 @@ in `c2l-csv-columns'." (kill-new entry) (message entry))) +(defun c2l-convert-region (start end) + "Convert the CSV entries in the region to ledger entries. +START and END describe the region. Note that it is assumed that +START does indeed refer to the start of the region and END to its +end. In other words, START must be smaller than END. START and +END do not have to point to the start of end of a line, but the +conversion always takes the whole line into account. + +This function always returns nil. The converted entries are +placed in the buffer \"*Csv2Ledger Results*\", which is erased +beforehand if it already exists." + (interactive "r") + (let ((buffer (get-buffer-create "*Csv2Ledger Results*"))) +(with-current-buffer buffer + (erase-buffer)) +(save-mark-and-excursion + (goto-char start) + (beginning-of-line) + (while (< (point) end) +(let ((entry (c2l-csv-line-to-ledger (c2l-get-current-row + (with-current-buffer buffer +(insert entry "\n"))) +(forward-line 1) + (provide 'csv2ledger) ;;; csv2ledger.el ends here
[nongnu] elpa/csv2ledger 7a3c55377e 154/190: Small update to the README
branch: elpa/csv2ledger commit 7a3c55377e060de9f78f84782b250b4251e4d99e Author: Joost Kremers Commit: Joost Kremers Small update to the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ecd7168e15..1ec335fd74 100644 --- a/README.md +++ b/README.md @@ -240,7 +240,7 @@ The function `c2l-compose-entry` requires that at least the `date`, `title`, `am If you have to deal with more than one bank, most likely the CSV files from those banks will be different and require different settings for the options discussed here. You can deal with this using directory-local variables. -How to set up directory-local variables is discussed in the Emacs manual (see the Info node `(emacs) Directory Variables`). As an example, you can create a `.dir-locals.el` file with the following content: +How to set up directory-local variables is discussed in the Emacs manual (see the Info node `(emacs) Directory Variables`). As an example, a `.dir-locals.el` file with settings for `csv2ledger` would look something like the following: ``` ((csv-mode . ((c2l-accounts-file . "~/Finances/Accounts.ledger")
[nongnu] elpa/csv2ledger 93bd85b0e0 041/190: c2l-convert-region: Report number of converted entries.
branch: elpa/csv2ledger commit 93bd85b0e0b69758663f9fd457c51916a8be31cf Author: Joost Kremers Commit: Joost Kremers c2l-convert-region: Report number of converted entries. --- csv2ledger.el | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index eff8f98f66..2c088285ca 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -336,14 +336,17 @@ placed in the buffer \"*Csv2Ledger Results*\", which is erased beforehand if it already exists." (interactive "r") (let ((buffer (c2l-get-results-buffer)) +(n 0)) (save-mark-and-excursion (goto-char start) (beginning-of-line) (while (< (point) end) (let ((entry (c2l-csv-line-to-ledger (c2l-get-current-row + (setq n (1+ n)) (with-current-buffer buffer (insert entry "\n"))) -(forward-line 1) +(forward-line 1))) +(message "[Csv2Ledger] Converted %d entries." n))) (provide 'csv2ledger)
[nongnu] elpa/csv2ledger 0bcf56f4b8 140/190: Update the README.
branch: elpa/csv2ledger commit 0bcf56f4b850d27aa51bba81b11aa85a1862090d Author: Joost Kremers Commit: Joost Kremers Update the README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba55437c6d..053cfb2f09 100644 --- a/README.md +++ b/README.md @@ -185,7 +185,7 @@ Another possible use of `c2l-field-modify-functions` is to make sure the value o ### Modifying the transaction ### -One limitation of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of some other field or fields in the transaction. If you need to make such a change, you add a function to the option `c2l-transaction-modify-functions`. This option holds a list of functions that take the entire transaction as its argument and return a modified transaction. +One limitation of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of some other field or fields in the transaction, or if you want to add new fields. If you need to make such a change, you add a function to the option `c2l-transaction-modify-functions`. This option holds a list of functions that take the entire transaction as its argument and return a modifi [...] The transaction is passed as an alist of field-value pairs, with the fields being symbols and the values being strings. For example, for the ledger entry shown above, the transaction would be as follows:
[nongnu] elpa/csv2ledger e6a7312467 112/190: Small updates to the README.
branch: elpa/csv2ledger commit e6a7312467200f32b3fd54cc5f9bf9ed5f3eae19 Author: Joost Kremers Commit: Joost Kremers Small updates to the README. --- README.md | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f2bdc1e9da..9ee07d02ad 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ If you have this information in your CSV file, you can use it and add it to the ## Setup ## -At the very least, you will need to set two user options: `c2l-base-account` and `c2l-csv-columns`. `c2l-base-account` is the account that represents your bank account in your ledger file. By default, `c2l-base-account` is set to `Assets:Checking`. `c2l-csv-columns` is a list of column names representing the columns in your CSV file. The following column names are meaningful to `csv2ledger:` +At the very least, you will need to set two user options: `c2l-base-account` and `c2l-csv-columns`. `c2l-base-account` is the account that represents your bank account in your ledger file. By default, it is set to `Assets:Checking`. `c2l-csv-columns` is a list of column names representing the columns in your CSV file. The following column names are meaningful to `csv2ledger:` - `date`: booking date of the transaction - `posted`: effective date of the transaction @@ -52,13 +52,13 @@ The `amount` field is indented for the CSV field that contains the amount of the The `description` and `posted` fields are entirely optional. If you have them and wish to include them in the ledger entry, add them to `c2l-csv-columns`. If you do not wish them included in the ledger entries, leave them out. -Note that `c2l-csv-columns` should contain a column name for each column in your CSV files. If there are columns that you wish to ignore, use an underscore for them. For example, the CSV files from my bank have an effective (posted) date in them as the second element, but it is almost always identical to the booking date and does not provide me with any useful information. Furthermore, they also an additional final column with the balance, which `csv2ledger` doesn't use. Therefore, I set [...] +Note that `c2l-csv-columns` should contain a column name for each column in your CSV files. If there are columns that you wish to ignore, use an underscore for them. For example, the CSV files from my bank have an effective (posted) date in them as the second element, but it is almost always identical to the booking date and does not provide me with any useful information. Furthermore, they also have an additional final column with the balance, which `csv2ledger` doesn't use. Therefore, [...] ```emacs-lisp (setq c2l-csv-columns '(date _ type description sender payee amount _)) ``` -One more thing to note here: I have a `type` field in this list. In my CSV files, this field indicates whether the transaction is a bank transfer, an ATM withdrawal, a card payment at a store, etc. By default, `csv2ledger` itself does not do anything with the `type` field, but with some additional configuration, you can make use of such extra information in several ways, as discussed below. +Note that I have a `type` field in this list. In my CSV files, this field indicates whether the transaction is a bank transfer, an ATM withdrawal, a card payment at a store, etc. By default, `csv2ledger` itself does not do anything with the `type` field, but with some additional configuration, you can make use of such extra information in several ways, as discussed below. ## Running the conversion ## @@ -166,7 +166,6 @@ The transaction will be passed as an alist of field-value pairs. For example, fo (sender . "account holder") (payee . "Aldi Supermarket") (amount . "-€25.10")) - ``` Note that the functions in `c2l-field-modify-functions` are applied before `c2l-transaction-modify-functions`, which is why the values for `date` and `amount` already appear in their modified forms here.
[nongnu] elpa/csv2ledger cc5050faaf 117/190: Fix doc string for c2l-create-amount
branch: elpa/csv2ledger commit cc5050faafdb068e5a40aecff93e3e8037a6e428 Author: Joost Kremers Commit: Joost Kremers Fix doc string for c2l-create-amount --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 97509ea1f0..f4104df0bb 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -270,7 +270,7 @@ Return the modified transaction." transaction)) (defun c2l-create-amount (transaction) - "Create the amountfor TRANSACTION. + "Create the amount for TRANSACTION. Return the modified transaction." (unless (c2l--amount-p (alist-get 'amount transaction "")) (let ((amount (or (c2l--amount-p (alist-get 'credit transaction ""))
[nongnu] elpa/csv2ledger c5b7b0766e 024/190: Rewrite `c2l-compose-entry` and `c2l-csv-line-to-ledger`.
branch: elpa/csv2ledger commit c5b7b0766e622e7088c0394b764ffa6800938c57 Author: Joost Kremers Commit: Joost Kremers Rewrite `c2l-compose-entry` and `c2l-csv-line-to-ledger`. Adapt both functions to the new user options, which provide more customisability. --- csv2ledger.el | 66 +-- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 179933ad63..245daddf54 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -145,7 +145,6 @@ returns a match wins." (defvar c2l--accounts nil "List of ledger accounts, mainly used for completion.") (defvar c2l--compiled-matcher-regexes nil "Alist of accounts and their matchers.") -(defun c2l-compose-entry (date title amount &optional description from to) (defun c2l-convert-little-endian-to-iso8601-date (date) "Convert DATE from a little-endian format to an ISO 8601 format. DATE should be a string representing a date of the form @@ -172,22 +171,35 @@ returned, otherwise the payee is returned." sender payee))) +(defun c2l-compose-entry (items &optional from to) "Create a ledger entry. -DATE, TITLE, AMOUNT are used to create the entry. DESCRIPTION, -if non-nil, is added as a comment, preceded by \"Desc:\". FROM -is the account where the money comes from, TO the account to +ITEMS is an alist containing (key . value) pairs that should be +included in the entry. It should contain values for the keys +`date', `payee', `sender' and `amount'. ITEMS may also contain a +value for `description'. If it is present, it is added as a +comment, preceded by \"Desc:\". + +FROM is the account where the money comes from, TO the account to which it goes. Note that if AMOUNT is negative, these roles are -reversed." - ;; TODO Fix doc string +reversed. FROM and TO default to `c2l-fallback-account' and +`c2l-base-account', respectively." + (or from (setq from c2l-fallback-account)) (or to (setq to c2l-base-account)) - (setq amount (c2l-parse-amount amount)) - (let ((width ledger-post-amount-alignment-column)) -(concat (c2l-parse-date date) " * " title "\n" -(if description (format "; Desc: %s\n" description) "") -(format "%s\n" (or from c2l-fallback-account)) -(format "%s " to) -(make-string (- width 4 (length to) 2 (length amount)) ?\s) -amount "\n"))) + (let* ((width ledger-post-amount-alignment-column) + (parsed-items (mapcar (lambda (item) + (let ((field (car item)) + (value (cdr item))) + (cons field + (funcall (alist-get field c2l-field-parse-functions #'identity) value + items)) + (title (funcall c2l-title-function parsed-items))) +(let-alist parsed-items + (concat .date (if .valuation (format "=%s " .valuation) "") (if c2l-auto-reconcile " *" "") " " title "\n" + (if (and .description (not (string-empty-p .description))) (format "; Desc: %s\n" .description) "") + (format "%s\n" from) + (format "%s " to) + (make-string (- width 4 (length to) 2 (length .amount)) ?\s) + .amount "\n" (defun c2l-read-accounts (file) "Read list of accounts from FILE." @@ -241,21 +253,17 @@ for that account." (defun c2l-csv-line-to-ledger (row) "Convert ROW to a ledger entry. -ROW is a list of strings and should have the following elements: - -Date Valuation Type Description Sender Payee Amount Balance - -Valuation and Balance are ignored, the other elements are used to -create the ledger entry." - (pcase-let* ((`(,date ,_ ,type ,description ,sender ,payee ,amount ,_) row) - (title (if (and (stringp c2l-account-holder) - (string-match-p c2l-account-holder payee)) - sender -payee)) - (account (or (seq-some #'c2l-match-account (list description payee type sender)) -(completing-read (format "Account for transaction %s, %s «%.75s» " title amount description) c2l--accounts nil t))) - (entry (c2l-compose-entry date title amount description account))) -entry)) +ROW contains the data of the entry as a list of strings. The +strings are interpreted according to the template in +`c2l-csv-columns'." + (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) + (account (or (-some #'c2l-match-account (mapcar #'cdr (--filter (memq (car it) c2l-title-match-fields) fields))) + (completing-read (format "Account for transaction %s, %s «%.75s» " + (funcall c2l-title-function fields) + (alist-get 'amount f
[nongnu] elpa/csv2ledger 3a309c795a 139/190: Fix the README.
branch: elpa/csv2ledger commit 3a309c795ad3f88732306d33245fe93ea000bea9 Author: Joost Kremers Commit: Joost Kremers Fix the README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd492aff64..ba55437c6d 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ The setting for `c2l-field-modify-functions` then ends up like this: ```emacs-lisp (setopt c2l-field-modify-functions '((date . c2l-convert-little-endian-to-iso8601-date) -(amount . jk/c2l-convert-postbank-to-ledger-amount))) +(amount . jk/c2l-convert-amount))) ``` Another possible use of `c2l-field-modify-functions` is to make sure the value of the `debit` field is is a negative value. For example, if your CSV file lists amounts debit as `"€25.14"` instead of `"-€25.14"`, you can change this with the following setup:
[nongnu] elpa/csv2ledger c72b617d68 159/190: Fix typo in the README
branch: elpa/csv2ledger commit c72b617d68b29b1b40d0c3ae8ed2b2da2da2f94a Author: Joost Kremers Commit: Joost Kremers Fix typo in the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b588e45f6c..833a435be4 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ How to set up directory-local variables is discussed in the Emacs manual (see th (c2l-auto-cleared . t ``` -This will apply all listed `c2l` settings to all CSV files in the directory in containing the `.dir-locals.el` file. As long as you keep the CSV files from the two banks in different directories, you can use this strategy to set them up differently. +This will apply all listed `c2l` settings to all CSV files in the directory containing the `.dir-locals.el` file. As long as you keep the CSV files from the two banks in different directories, you can use this strategy to set them up differently. If you prefer to keep your `csv2ledger` configuration in your init file, you can use the functions `dir-locals-set-directory-class` and `dir-locals-set-class-variables` to set up directory-local variables for specific directories. The Info node mentioned above explains how to do this.
[nongnu] elpa/csv2ledger b57b06d3a0 163/190: Update the README.
branch: elpa/csv2ledger commit b57b06d3a07ee2aef1c96404ce1bc21ecde8b3e1 Author: Joost Kremers Commit: Joost Kremers Update the README. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc2fc8de7e..5eb6670dab 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,8 @@ Note that if you wish, you can completely forego the account matching mechanism ## Modifying field values ## -Sometimes, it is useful or even necessary to modify the value of some field extracted from the CSV file, e.g., when dates or amounts do not appear in a format that Ledger can use. There are two ways that allow you to do so. +Sometimes, it is useful or even necessary to modify the value of some field extracted from the CSV file, e.g., when dates or amounts do not appear in a format that Ledger can use. `csv2ledger` provides two ways of doing this: you can modify individual fields, which is fairly simple but also limited in some ways, or you can modify the entire transaction, which requires a bit more programming but is more powerful. + ### Modifying individual fields ### @@ -177,7 +178,7 @@ The setting for `c2l-field-modify-functions` then ends up like this: (amount . jk/c2l-convert-amount))) ``` -Another possible use of `c2l-field-modify-functions` is to make sure the value of the `debit` field is is a negative value. For example, if your CSV file lists amounts debit as `"€25.14"` instead of `"-€25.14"`, you can change this with the following setup: +Another possible use of `c2l-field-modify-functions` is to make sure the value of the `debit` field is a negative value. For example, if your CSV file lists amounts debit as `"€25.14"` instead of `"-€25.14"`, you can change this with the following setup: ```emacs-lisp (setopt c2l-field-modify-functions
[nongnu] elpa/csv2ledger 7d75cd4c41 166/190: Update README.
branch: elpa/csv2ledger commit 7d75cd4c416dfc55f2a8c849ae581c53f08c08f3 Author: Joost Kremers Commit: Joost Kremers Update README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95ce8eeed6..4b2ee1849f 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ restaurantExpenses:Leisure:Restaurant Set the option `c2l-account-matchers-file` to point to this file. With the example matchers shown here, if the payee or description of a transaction contains the string `"aldi"`, `Expenses:Groceries` is taken as the balancing account. There can be more than one matcher for one account: in the example, both `"aldi"` and `"lidl"` link to the account `Expenses:Groceries`. -The matchers are simple substrings, not regular expressions. I have not found the need to use regular expressions for account matching, and prefer the simplicity of not having to worry about the special meaning of certain characters in them. Internally, however, the matchers are turned into regular expressions and stored in the variable `c2l-matcher-regexps`. If you prefer to use regular expressions, you can set this variable yourself. Its value should be an alist mapping regular express [...] +The matchers are simple substrings, not regular expressions. I have not found any need for regular expressions for account matching, and prefer the simplicity of simple substrings. Internally, however, the matchers are turned into regular expressions and stored in the variable `c2l-matcher-regexps`. If you prefer to use regular expressions, you can set this variable yourself. Its value should be an alist mapping regular expressions to accounts: ```emacs-lisp (setq c2l-matcher-regexps '(("\\(?:aldi\\|lidl\\)" . "Expenses:Groceries")
[nongnu] elpa/csv2ledger ae252fe149 060/190: Rename c2l-fallback-balancing-account back to c2l-fallback-account.
branch: elpa/csv2ledger commit ae252fe14981cf500a455c3f47f5f98744be538f Author: Joost Kremers Commit: Joost Kremers Rename c2l-fallback-balancing-account back to c2l-fallback-account. --- csv2ledger.el | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index bd4c39eaa2..1057e4a3fc 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -62,7 +62,7 @@ files are processed." :group 'csv2ledger :local t) -(defcustom c2l-fallback-balancing-account nil +(defcustom c2l-fallback-account nil "Fallback for the balancing account in transactions. When creating a ledger entry, csv2ledger tries to determine the balancing account for the transaction based on the matchers in @@ -197,9 +197,9 @@ comment, preceded by \"Desc:\". FROM is the account where the money comes from, TO the account to which it goes. Note that if AMOUNT is negative, these roles are -reversed. FROM and TO default to `c2l-fallback-balancing-account' and +reversed. FROM and TO default to `c2l-fallback-account' and `c2l-base-account', respectively." - (or from (setq from c2l-fallback-balancing-account)) + (or from (setq from c2l-fallback-account)) (or to (setq to c2l-base-account)) (let* ((parsed-items (mapcar (lambda (item) (let ((field (car item)) @@ -283,7 +283,7 @@ found, the value of `c2l-fallback-account' is used. If that option is unset, the user is asked for an account." (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-balancing-match-fields) fields))) - c2l-fallback-balancing-account + c2l-fallback-account (completing-read (format "Account for transaction %s, %s «%.75s» " (funcall c2l-title-function fields) (alist-get 'amount fields)
[nongnu] elpa/csv2ledger 3925c6b34a 113/190: Small fixes to the README.
branch: elpa/csv2ledger commit 3925c6b34ad6eaaa4395bfd7ee0bb1c7d00ce7e2 Author: Joost Kremers Commit: Joost Kremers Small fixes to the README. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9ee07d02ad..d5ad9e87be 100644 --- a/README.md +++ b/README.md @@ -188,14 +188,14 @@ The particular function that takes care of this is `c2l-create-title` and it is The second function in `c2l-transaction-modify-functions` is a function to create the amount, imaginatively called `c2l-create-amount`. This function does not do anything if there is an `amount` field in the transaction and its value looks like an amount. If this is not the case, it checks if there is a `credit` or `debit` field and sees if either of those have a value that looks like an amount. If either of them exists and has an amount, it is added to the transaction as the `amount` field. -If you need to replace this function with a custom function, note that it is important that it creates an `amount` field in the transaction and that its value is an amount, because that is what is eventually used to construct the entry. If a transaction does not have an `amount` field after the functions in `c2l-transaction-modify-functions` have been applied, the ledger entry will lack an amount and will be invalid. +If you need to replace this function with a custom function, note that it is important that it creates an `amount` field in the transaction, because that is what is eventually used to construct the entry. If a transaction does not have an `amount` field after the functions in `c2l-transaction-modify-functions` have been applied, the ledger entry will lack an amount and will be invalid. Another important point to note is that the amount in the `amount` field must be a negative amount if it's an amount debit, i.e., it must have a minus sign. If you have a separate `debit` column in your CSV files with amounts that are not negative, make sure to add a minus sign. The easiest way to do this is in `c2l-field-modify-functions`. ### Setting the account (v. 2) ### -The third function in `c2l-transaction-modify-functions`is `c2l-create-account`. This is the function that checks the fields of the transaction against the account matchers, and if one is not found, uses `c2l-fallback-account` or asks the user. If you wish to use a different method to set the account, you can replace this function with a custom one. It needs to add an `account` field to the transaction, but there are no restrictions on how the account is determined. +The third function in `c2l-transaction-modify-functions` is `c2l-create-account`. This is the function that checks the fields of the transaction against the account matchers, and if one is not found, uses `c2l-fallback-account` or asks the user. If you wish to use a different method to set the account, you can replace this function with a custom one. It needs to add an `account` field to the transaction, but there are no restrictions on how the account is determined. ### Creating the entry ###
[nongnu] elpa/csv2ledger 03b2aeb4a7 056/190: Update the README.
branch: elpa/csv2ledger commit 03b2aeb4a73845096854fbbb2822d79827f65145 Author: Joost Kremers Commit: Joost Kremers Update the README. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 11b8293a5e..85201dcf9e 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ This means that the `description` field is checked first, then the `payee`, then Note that this is the *only* reason for including the `type` field in `c2l-csv-columns` above: I use its value to help determine the target account. As mentioned, the `type` field is not included in the ledger entry. + ## Modifying field values ## Depending on the format of your CSV file, it may also be necessary to set the variable `c2l-field-parse-functions`. This is a list mapping fields to functions that take the field's value and convert it to something else. For example, my CSV files provide the date in the format `DD.MM.`, but ledger expects them to be in the format `-MM-DD`. `csv2ledger` comes with a function that performs this conversion, `c2l-convert-little-endian-to-iso8601-date`. I therefore set `c2l-field-pars [...] @@ -114,6 +115,8 @@ You can then add this to `c2l-field-parse-functions`: (amount . c2l-convert-postbank-to-ledger-amount))) ``` +By default, ledger entries are created uncleared. If you want to mark all transactions as cleared, set the variable `c2l-auto-cleared`. + A final variable you may want to set is `c2l-alignment-column`. This should most likely have the same value as `ledger-post-amount-alignment-column`, although `csv2ledger` currently assumes that `ledger-post-amount-alignment-at` is set to `:end` and that the commodity precedes the amount. If either is not true, alignment is probably not optimal.
[nongnu] elpa/csv2ledger 466a098d2b 034/190: Extract new function `c2l-get-current-row` from `c2l-csv-entry-as-kill`.
branch: elpa/csv2ledger commit 466a098d2b845c99a1aba8947d708e09c52b0013 Author: Joost Kremers Commit: Joost Kremers Extract new function `c2l-get-current-row` from `c2l-csv-entry-as-kill`. --- csv2ledger.el | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 9ce636e67f..c0c150562a 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -270,6 +270,14 @@ strings are interpreted according to the template in c2l--accounts (c2l-compose-entry fields account))) +(defun c2l-get-current-row () + "Read the current line as a CSV row. +Return value is a list of values as strings." + (let ((separator (car csv-separator-chars)) +(quote-char (string-to-char (or (car csv-field-quotes) ""))) +(line (buffer-substring-no-properties (point-at-bol) (point-at-eol +(parse-csv-string line separator quote-char))) + ;;;###autoload (defun c2l-set-base-account () "Set `c2l-base-account'." @@ -285,10 +293,7 @@ in `c2l-csv-columns'." (interactive) (unless c2l--accounts (setq c2l--accounts (c2l-read-accounts c2l-accounts-file))) - (let* ((separator (car csv-separator-chars)) - (quote-char (string-to-char (or (car csv-field-quotes) ""))) - (line (buffer-substring-no-properties (point-at-bol) (point-at-eol))) - (row (parse-csv-string line separator quote-char)) + (let* ((row (c2l-get-current-row)) (entry (c2l-csv-line-to-ledger row))) (kill-new entry) (message entry)))
[nongnu] elpa/csv2ledger 40e1230600 059/190: Fix doc string of `c2l--csv-line-to-ledger`.
branch: elpa/csv2ledger commit 40e1230600636366c2a0a73c3bff1cf6dbec9eed Author: Joost Kremers Commit: Joost Kremers Fix doc string of `c2l--csv-line-to-ledger`. --- csv2ledger.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 3557add0a6..bd4c39eaa2 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -277,9 +277,9 @@ for that account." ROW contains the data of the entry as a list of strings. The strings are interpreted according to the template in `c2l-csv-columns'. The transaction is booked to the account in -`c2l-base-account'. The reverse account is determined on the +`c2l-base-account'. The balancing account is determined on the basis of the matchers in `c2l-account-matchers-file'. If none is -found, the value of `c2l-fallback-balancing-account' is used. If +found, the value of `c2l-fallback-account' is used. If that option is unset, the user is asked for an account." (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-balancing-match-fields) fields)))
[nongnu] elpa/csv2ledger 799beb345b 035/190: New function `c2l-has-header`.
branch: elpa/csv2ledger commit 799beb345b5f8381d163a638dbdf74498d5fb738 Author: Joost Kremers Commit: Joost Kremers New function `c2l-has-header`. --- csv2ledger.el | 11 +++ 1 file changed, 11 insertions(+) diff --git a/csv2ledger.el b/csv2ledger.el index c0c150562a..b7583574b0 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -278,6 +278,17 @@ Return value is a list of values as strings." (line (buffer-substring-no-properties (point-at-bol) (point-at-eol (parse-csv-string line separator quote-char))) +(defun c2l-has-header () + "Return non-nil if the current CSV buffer appears to have a header. +Essentially, this function just takes the field that should +contain the amount and checks if it contains something that looks +like a number." + (save-mark-and-excursion +(goto-char (point-min)) +(let* ((row (c2l-get-current-row)) + (fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row + (not (string-match-p "[0-9,.-]+" (alist-get 'amount fields)) + ;;;###autoload (defun c2l-set-base-account () "Set `c2l-base-account'."
[nongnu] elpa/csv2ledger d00914d9f1 044/190: c2l-csv-line-to-ledger: Check c2l-fallback-account before asking the user.
branch: elpa/csv2ledger commit d00914d9f1c8742f7edebd67d3a477be02a5 Author: Joost Kremers Commit: Joost Kremers c2l-csv-line-to-ledger: Check c2l-fallback-account before asking the user. --- csv2ledger.el | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 233b0af021..8f169107e9 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -261,9 +261,14 @@ for that account." "Convert ROW to a ledger entry. ROW contains the data of the entry as a list of strings. The strings are interpreted according to the template in -`c2l-csv-columns'." +`c2l-csv-columns'. The transaction is booked to the account in +`c2l-base-account'. The reverse account is determined on the +basis of the matchers in `c2l-account-matchers-file'. If none is +found, the value of `c2l-fallback-account' is used. If that +option is unset, the user is asked for an account." (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) (account (or (-some #'c2l-match-account (mapcar #'cdr (--filter (memq (car it) c2l-title-match-fields) fields))) + c2l-fallback-account (completing-read (format "Account for transaction %s, %s «%.75s» " (funcall c2l-title-function fields) (alist-get 'amount fields)
[nongnu] elpa/csv2ledger 2531e81bcf 082/190: Add user option c2l-transaction-modify-function.
branch: elpa/csv2ledger commit 2531e81bcf80591db001904164990f7b08af74e5 Author: Joost Kremers Commit: Joost Kremers Add user option c2l-transaction-modify-function. --- csv2ledger.el | 26 +++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 1e3c733a9c..48b1bbea20 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -120,6 +120,17 @@ set them directly." (c2l-set-options))) :group 'csv2ledger) +(defcustom c2l-transaction-modify-function #'identity + "Function to modify a transaction. +This should be a single function that takes an alist representing +a transaction and returns a modified alist. Any kind of +modification is possible, including modifying, adding or deleting +fields. Importantly, because the function is passed the entire +entry, it is possible to modify or create a field based on the +values of other fields." + :type 'function + :group 'csv2ledger) + (defcustom c2l-field-modify-functions nil "List of functions to modify fields in an entry. This option should be an alist mapping field names (as symbols) @@ -360,8 +371,15 @@ strings are interpreted according to the template in `c2l-base-account'. The target account is determined on the basis of the matchers in `c2l-account-matchers-file'. If none is found, the value of `c2l-fallback-account' is used. If that -option is unset, the user is asked for an account." - (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) +option is unset, the user is asked for an account. + +This function first creates an alist of field-value pairs, then +passes it to `c2l-transaction-modify-function' and subsequently +applies the functions in `c2l-field-modify-functions' to the +individual fields. After that, the `title' and `account' fields +are added. Additionally, the `amount' field is added or, if +already, present, its value is updated." + (let* ((fields (funcall c2l-transaction-modify-function (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row (parsed-fields (mapcar (lambda (item) (let ((field (car item)) (value (cdr item))) @@ -379,7 +397,9 @@ option is unset, the user is asked for an account." c2l--accounts (push (cons 'account account) parsed-fields) (push (cons 'title title) parsed-fields) -(push (cons 'amount amount) parsed-fields) +(if (assq 'amount parsed-fields) +(setf (alist-get 'amount parsed-fields) amount) + (push (cons 'amount amount) parsed-fields)) (c2l--compose-entry parsed-fields))) (defun c2l--get-current-row ()
[nongnu] elpa/csv2ledger 39cefb514c 128/190: Add installation section to README.
branch: elpa/csv2ledger commit 39cefb514ca08b75e3cdd7a94140353bf7cd1b63 Author: Joost Kremers Commit: Joost Kremers Add installation section to README. --- README.md | 9 + 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 0575339724..014b9c64e1 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,15 @@ Not indicated in the above example is the *effective* date (also called *posted* If you have this information in your CSV file, you can use it and add it to the entry. If such an effective date is found, the entry is also marked as cleared, i.e., an asterisk appears between the date and the title. +## Installation ## + +For the moment, `csv2ledger` needs to be installed manually. Put the file `csv2ledger.el` in your load path, byte-compile it if you wish, and `require` it in your init file. + +Make sure to install the dependencies as well: `csv-mode` from GNU ELPA, and `parse-csv` and `dash` from Melpa. Note that for `csv2ledger` to work properly, CSV files must be opened in buffers with `csv-mode` as the major mode. This should work automatically after installing `csv-mode`, but if you have issues, make sure to check this. + +The advantage of `csv-mode` is that it will also handle CSV files that use semicolon or TAB as separator (even if they have a `.csv` suffix). The separator should be recognised automatically without any user intervention. + + ## Customisation ## Several customisation options are present. The full list with a short explanation is presented here, but most of these options are discussed in more detail below.
[nongnu] elpa/csv2ledger ae65a1f36b 120/190: Update README.
branch: elpa/csv2ledger commit ae65a1f36b94c3919d9858c8d0f012149533 Author: Joost Kremers Commit: Joost Kremers Update README. --- README.md | 29 ++--- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d5ad9e87be..59fab0f8b9 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The purpose of this small library is to read bank transactions in a CSV file and The description is optional, you can leave it out if you prefer. The format used for the amount is also configurable. By default, `csv2ledger` just copies the amount from the CSV file, but you can apply a conversion to it if you like. -For ease of reference, I will use the following terms to refer to the various parts of the entry. The account associated with the bank account for the CSV file is called the *base* account. In the example here, it is `Assets:Checkings`. The other account, here `Expenses:Groceries`, is the *balancing account*, though I also refer to it as the *target account*. The real-life entity associated with the balancing account, here "Aldi Supermarket" is often called the payee, but since I general [...] +For ease of reference, I will use the following terms to refer to the various parts of the entry. The account associated with the bank account for the CSV file is called the *base* account. In the example here, it is `Assets:Checkings`. The other account, here `Expenses:Groceries`, is the *balancing account*, though I also refer to it as the *target account*. The real-life entity associated with the balancing account, here "Aldi Supermarket" is often called the payee, but since I general [...] Not indicated in the above example is the *effective* date (also called *posted*). This is the date that may follow the booking date, separated by an equal sign: @@ -33,7 +33,10 @@ If you have this information in your CSV file, you can use it and add it to the ## Setup ## -At the very least, you will need to set two user options: `c2l-base-account` and `c2l-csv-columns`. `c2l-base-account` is the account that represents your bank account in your ledger file. By default, it is set to `Assets:Checking`. `c2l-csv-columns` is a list of column names representing the columns in your CSV file. The following column names are meaningful to `csv2ledger:` +At the very least, you will need to set two user options: `c2l-base-account` and `c2l-csv-columns`. `c2l-base-account` is the account that represents your bank account in your ledger file. By default, it is set to the value `"Assets:Checking"`. + + +`c2l-csv-columns` is a list of column labels representing the columns in your CSV file. Note that these column labels should **not** be set to the column names in your CSV file. Rather, they should indicate to `csv2ledger` what type of data each column contains. The following column names are meaningful to `csv2ledger`: - `date`: booking date of the transaction - `posted`: effective date of the transaction @@ -44,7 +47,7 @@ At the very least, you will need to set two user options: `c2l-base-account` and - `credit`: the amount received - `debit`: the amount payed -Note that the column names are symbols. In the default setup, all these fields may be used to create the Ledger entry, though some of them are only used in specific circumstances. +In the default setup, all these fields may be used to create the Ledger entry, though some of them are only used in specific circumstances. First, `payee` and `sender` never appear both. By default, `payee` is used as the title of the ledger entry and `sender` is ignored. If you set the option `c2l-account-holder` however, the `sender` will be used as the title for transactions in which you are the payee, i.e., when you receive money. If you do not have a `sender` field in your CSV files, you may simply leave it out. In that case, the `payee` will always be used as the title, at least in the default setup. @@ -58,7 +61,11 @@ Note that `c2l-csv-columns` should contain a column name for each column in your (setq c2l-csv-columns '(date _ type description sender payee amount _)) ``` -Note that I have a `type` field in this list. In my CSV files, this field indicates whether the transaction is a bank transfer, an ATM withdrawal, a card payment at a store, etc. By default, `csv2ledger` itself does not do anything with the `type` field, but with some additional configuration, you can make use of such extra information in several ways, as discussed below. +If you set `c2l-csv-columns` in your init file, keep in mind that the column labels are symbols, not strings. + +Note that I have a `type` field in this list, which is not in the list of "meaningful" fields just above. You can, in fact, add any field to `c2l-csv-columns` that you like. By default, `csv2ledger` does not do anything with such user-defined fields, but with some additional configuration, you can make
[nongnu] elpa/csv2ledger 07281e2558 097/190: Update to the README.
branch: elpa/csv2ledger commit 07281e25588980ac6ecb8ebc5585daf82fad1414 Author: Joost Kremers Commit: Joost Kremers Update to the README. --- README.md | 36 ++-- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fc1ecd1c74..607d68996d 100644 --- a/README.md +++ b/README.md @@ -95,12 +95,16 @@ Two things are of note here: first, the order of this list determines the order ## Modifying field values ## -TODO +If you wish or need to modify the values extracted from the CSV file in some way, there are several user options that allow you to do so. + +First, there is the option `c2l-field-modify-functions`. This is an alist mapping field names to functions. Each function should take a string as its only argument and return a string. These functions are called with the field's value as argument and the return value is used to construct the entry. -Depending on the format of your CSV file, it may also be necessary to set the variable `c2l-field-parse-functions`. This is a list mapping fields to functions that take the field's value and convert it to something else. For example, my CSV files provide the date in the format `DD.MM.`, but ledger expects them to be in the format `-MM-DD`. `csv2ledger` comes with a function that performs this conversion, `c2l-convert-little-endian-to-iso8601-date`. I therefore set `c2l-field-pars [...] +As an example, my CSV files provide the date in the format `DD.MM.`, but ledger expects them to be in the format `-MM-DD`. To remedy this, `csv2ledger` comes with the function `c2l-convert-little-endian-to-iso8601-date` that takes a date in the format `DD.MM.` and converts it to `-MM-DD`. For convenience, it also accepts dates in the forms `DD-MM-` and `DD/MM/`. + +To use this function to modify the `date` field, I set `c2l-field-parse-functions` like this: ``` -(setq c2l-field-parse-functions +(setq c2l-field-modify-functions '((date . c2l-convert-little-endian-to-iso8601-date))) ``` @@ -120,15 +124,35 @@ to \"-€3150.20\"." (concat sign "€" euros "." cents))) ``` -You can then add this to `c2l-field-parse-functions`: +The setting for `c2l-field-parse-functions` then ends up like this: ``` -(setq c2l-field-parse-functions +(setq c2l-field-modify-functions '((date . c2l-convert-little-endian-to-iso8601-date) (amount . c2l-convert-postbank-to-ledger-amount))) ``` -By default, ledger entries are created uncleared. If you want to mark all transactions as cleared, set the variable `c2l-auto-cleared`. +One potential disadvantage of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of the other fields in the transaction. If you need to make such a change to the transaction, you can set the option `c2l-transaction-modify-function` to a function that takes the entire transaction as its argument and returns a modified transaction. + +The transaction will be passed as an alist of field-value pairs. For example, for the ledger entry shown above, the transaction would be something like this: + +``` +((date . "17.20.2022") + (description . "Referenz 999XXX999 ALDI SAGT DANKE") + (sender . "account holder") + (payee . "Aldi Supermarket") + (amount . "-25,10 €")) + +``` + +Your function can make any change to the transaction you wish. The only requirement is that the modified transaction contains at least the fields `date`, `payee` and either `amount` or `debit` and `credit`, because `csv2ledger` needs them to construct the ledger entry. + +Note that in this transaction alist, the values for date and amount have not been modified by the functions if `c2l-field-modify-functions`. This is because `c2l-transaction-modify-function` is called first. The result of that function is passed to the functions in `c2l-field-modify-functions`. In principle, `c2l-transaction-modify-function` can do anything `c2l-field-modify-functions` can do, but the latter type of function is conceptually simpler, which is why it's included here. + +You may also notice that the transaction alist does not contain a value for `title`. The `title` field is added to the transaction alist after the functions in `c2l-field-modify-functions` have been applied. + +TODO + A final variable you may want to set is `c2l-alignment-column`. This should most likely have the same value as `ledger-post-amount-alignment-column`, although `csv2ledger` currently assumes that `ledger-post-amount-alignment-at` is set to `:end` and that the commodity precedes the amount. If either is not true, alignment is probably not optimal.
[nongnu] elpa/csv2ledger 97ee04eb27 141/190: Fix default values of user options in the README.
branch: elpa/csv2ledger commit 97ee04eb274c99864221cdab7290c5d72604364b Author: Joost Kremers Commit: Joost Kremers Fix default values of user options in the README. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 053cfb2f09..801d289105 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,12 @@ Several customisation options are present. The full list with a short explanatio - `c2l-base-account` (`"Assets:Checking"`) — Account of the CSV file. - `c2l-fallback-account` (`nil`) — Target account if one cannot be determined automatically. - `c2l-account-holder` (`nil`) — Name of the account holder that may appear as payee or sender. -- `c2l-csv-columns` (`'()`) — List describing the columns in the CSV file. +- `c2l-csv-columns` (`()`) — List describing the columns in the CSV file. - `c2l-transaction-modify-functions` (`'(c2l-create-title c2l-create-amount c2l-create-account)`) — Functions used to modify the transaction data. - `c2l-field-modify-functions` (`nil`) — Functions used to modify field values. -- `c2l-entry-function` (`#'c2l-compose-entry`) — Function used to create the actual ledger transaction. +- `c2l-entry-function` (`c2l-compose-entry`) — Function used to create the actual ledger transaction. - `c2l-account-matchers-file` (`nil`) — File with substrings matching specific target accounts. -- `c2l-target-match-fields` (`'(payee description)`) — Fields in the transaction used to match against target accounts. +- `c2l-target-match-fields` (`(payee description)`) — Fields in the transaction used to match against target accounts. - `c2l-auto-cleared` (`nil`) — Whether to auto-clear transactions. - `c2l-alignment-column` (`52`) — Column to which the amount is aligned.
[nongnu] elpa/csv2ledger 59ba841805 086/190: Guard against empty payee and sender in c2l-title-is-payee-or-sender
branch: elpa/csv2ledger commit 59ba8418055359018f5ecb0e1aa12168b1eb4a39 Author: Joost Kremers Commit: Joost Kremers Guard against empty payee and sender in c2l-title-is-payee-or-sender --- csv2ledger.el | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index e30b42a890..2861bf615b 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -242,11 +242,16 @@ should contain values for `payee' and `sender'. If the value of otherwise the payee is returned." (let ((payee (alist-get 'payee transaction)) (sender (alist-get 'sender transaction))) -(if (stringp c2l-account-holder) -(if (string-match-p c2l-account-holder payee) -sender - payee) - payee))) +(cond + ((and (string-empty-p payee) + (string-empty-p sender)) + "Unknown") + ((string-empty-p payee) sender) + ((string-empty-p sender) payee) + ((and (stringp c2l-account-holder) + (string-match-p c2l-account-holder payee)) + sender) + (t payee (defun c2l-title-is-counterpart (transaction) "Return the counterpart of an entry.
[nongnu] elpa/csv2ledger 6076653a0f 084/190: Rename local variable in c2l--csv-line-to-ledger.
branch: elpa/csv2ledger commit 6076653a0f5353696ae45c09e99db79ab2656c51 Author: Joost Kremers Commit: Joost Kremers Rename local variable in c2l--csv-line-to-ledger. --- csv2ledger.el | 36 ++-- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 13f59c52f1..cda2b599b7 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -380,27 +380,27 @@ individual fields. After that, the `title' and `account' fields are added. Additionally, the `amount' field is added or, if already, present, its value is updated." (let* ((fields (funcall c2l-transaction-modify-function (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row - (parsed-fields (mapcar (lambda (item) - (let ((field (car item)) -(value (cdr item))) -(cons field - (funcall (alist-get field c2l-field-modify-functions #'identity) value -fields)) - (title (funcall c2l-title-function parsed-fields)) - (amount (funcall c2l-amount-function parsed-fields)) - (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-target-match-fields) parsed-fields))) + (modified-fields (mapcar (lambda (item) +(let ((field (car item)) + (value (cdr item))) + (cons field +(funcall (alist-get field c2l-field-modify-functions #'identity) value + fields)) + (title (funcall c2l-title-function modified-fields)) + (amount (funcall c2l-amount-function modified-fields)) + (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-target-match-fields) modified-fields))) c2l-fallback-account (completing-read (format "Account for transaction %s, %s «%.75s» " - (funcall c2l-title-function parsed-fields) - (alist-get 'amount parsed-fields) - (alist-get 'description parsed-fields)) + (funcall c2l-title-function modified-fields) + (alist-get 'amount modified-fields) + (alist-get 'description modified-fields)) c2l--accounts -(push (cons 'account account) parsed-fields) -(push (cons 'title title) parsed-fields) -(if (assq 'amount parsed-fields) -(setf (alist-get 'amount parsed-fields) amount) - (push (cons 'amount amount) parsed-fields)) -(c2l--compose-entry parsed-fields))) +(push (cons 'account account) modified-fields) +(push (cons 'title title) modified-fields) +(if (assq 'amount modified-fields) +(setf (alist-get 'amount modified-fields) amount) + (push (cons 'amount amount) modified-fields)) +(c2l--compose-entry modified-fields))) (defun c2l--get-current-row () "Read the current line as a CSV row.
[nongnu] elpa/csv2ledger 565e1a1c43 070/190: Add comment line denoting section for user option functions.
branch: elpa/csv2ledger commit 565e1a1c4369f8b9dc0071c741e17499e1f0aa0f Author: Joost Kremers Commit: Joost Kremers Add comment line denoting section for user option functions. --- csv2ledger.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/csv2ledger.el b/csv2ledger.el index d66e0cc094..1aa3189759 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -189,6 +189,8 @@ This should most likely be set to the same value as (defvar c2l--accounts nil "List of ledger accounts, mainly used for completion.") (defvar c2l--results-buffer nil "Buffer for conversion results.") +;;; Functions for use as values of customisation options. + (defun c2l-convert-little-endian-to-iso8601-date (date) "Convert DATE from a little-endian format to an ISO 8601 format. DATE should be a string representing a date of the form
[nongnu] elpa/csv2ledger c01946ab58 027/190: Do not try to read files that do not exist.
branch: elpa/csv2ledger commit c01946ab58e4d7f116fb680e7dea53833ee34674 Author: Joost Kremers Commit: Joost Kremers Do not try to read files that do not exist. --- csv2ledger.el | 40 +--- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index a4bddabeba..30387589c0 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -202,30 +202,32 @@ reversed. FROM and TO default to `c2l-fallback-account' and (defun c2l-read-accounts (file) "Read list of accounts from FILE." - (with-temp-buffer -(insert-file-contents file) -(goto-char (point-min)) -(let (accounts) - (while (not (eobp)) -(if (looking-at "^account \\([[:print:]]+\\)$") -(push (match-string 1) accounts)) -(forward-line 1)) - accounts))) + (when (file-readable-p file) +(with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (let (accounts) +(while (not (eobp)) + (if (looking-at "^account \\([[:print:]]+\\)$") + (push (match-string 1) accounts)) + (forward-line 1)) +accounts (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." - (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))) + (when (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 (defun c2l-compile-matcher-regexes (accounts) "Create efficient regular expressions for the matchers in ACCOUNTS.
[nongnu] elpa/csv2ledger 8e01e8379b 026/190: Update doc string of `c2l-base-account`.
branch: elpa/csv2ledger commit 8e01e8379b4e135ccde8aa24c79db1dfcbad28ad Author: Joost Kremers Commit: Joost Kremers Update doc string of `c2l-base-account`. Let us not check whether `c2l-base-account` is set. Nothing will break or be destroyed if it is not, the user can simply set the option and retry. It should be up to the user to configure csv2ledger correctly. --- csv2ledger.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index c2c298cd22..a4bddabeba 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -57,9 +57,8 @@ this bank account. As such, it is the account that will turn up in every transaction read from the CSV file. This is a buffer-local variable and can be set in the local -variable block of a CSV file. If its value is nil when invoking -`csv2ledger', the user is asked for a value. Setting a default -value is useful if one only has one back account from which CSV +variable block of a CSV file. Alternatively, one can set a +default value if one only has one back account from which CSV files are processed." :type 'file :group 'csv2ledger
[nongnu] elpa/csv2ledger 365faf54ed 094/190: Display the results buffer after conversion.
branch: elpa/csv2ledger commit 365faf54eda8c4e4bb954f657c1a6b46cb3f51a2 Author: Joost Kremers Commit: Joost Kremers Display the results buffer after conversion. --- csv2ledger.el | 1 + 1 file changed, 1 insertion(+) diff --git a/csv2ledger.el b/csv2ledger.el index f32bb87c9b..c30e1cca50 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -475,6 +475,7 @@ beforehand if it already exists." (with-current-buffer buffer (insert entry "\n"))) (forward-line 1))) +(display-buffer buffer) (message "[Csv2Ledger] Converted %d entries." n))) ;;;###autoload
[nongnu] elpa/csv2ledger 4f6bb9e1bd 184/190: Update example function jk/c2l-convert-amount in the README
branch: elpa/csv2ledger commit 4f6bb9e1bd7d634c6bfa2c1940ebfeaa742c1032 Author: Joost Kremers Commit: Joost Kremers Update example function jk/c2l-convert-amount in the README --- README.md | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 07bae19bfe..2d129bee8f 100644 --- a/README.md +++ b/README.md @@ -162,12 +162,15 @@ Since this is a very particular conversion, there is no function for it included ```emacs-lisp (defun jk/c2l-convert-amount (amount) - "Convert AMOUNT from the format \"-3.150,20 €\" to \"-€3150.20\"." - (string-match "\\(-\\)?\\([[:digit:].]+\\)\\(?:,\\([[:digit:]]\\{2\\}\\)\\)?" amount) + "Convert AMOUNT from the format \"-3.150,20 €\" to \"-€3150.20\". +This also handles cases such as \"300\" and \"8,7\"." + (string-match "\\(-\\)?\\([[:digit:].]+\\(?:,[[:digit:]]\\{2\\}\\)?\\)" amount) (let ((sign (or (match-string 1 amount) "")) -(euros (string-replace "." "" (match-string 2 amount))) -(cents (or (match-string 3 amount) "00"))) -(concat sign "€" euros "." cents))) +(amount (thread-last (match-string 2 amount) + (string-replace "." "") + (string-replace "," ".") + string-to-number))) +(format "%s€%.2f" sign amount))) ``` The setting for `c2l-field-modify-functions` then ends up like this:
[nongnu] elpa/csv2ledger 7635ee6fe3 007/190: Update "Created" year in header.
branch: elpa/csv2ledger commit 7635ee6fe30dc4c69c9ea432c43536b6a7d219df Author: Joost Kremers Commit: Joost Kremers Update "Created" year in header. --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 1cc32cb621..d3b81de1e5 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -5,7 +5,7 @@ ;; Author: Joost Kremers ;; Maintainer: Joost Kremers -;; Created: 2018 +;; Created: 2022 ;; Version: 1.0 ;; This file is NOT part of GNU Emacs.
[elpa] externals/ellama 9bd2641d8c 4/4: Update docs
branch: externals/ellama commit 9bd2641d8cea5c33f20f0114598403b55821d0d0 Author: Sergey Kostyaev Commit: Sergey Kostyaev Update docs --- README.org | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.org b/README.org index f559b0d9fd..5d308e8691 100644 --- a/README.org +++ b/README.org @@ -43,11 +43,12 @@ In that case you should customize ellama configuration like this: ;; could be llm-openai for example (require 'llm-ollama) (setopt ellama-provider - (make-llm-ollama -;; this model should be pulled to use it -;; value should be the same as you print in terminal during pull -:chat-model "mistral:7b-instruct-v0.2-q6_K" -:embedding-model "mistral:7b-instruct-v0.2-q6_K")) + (make-llm-ollama + ;; this model should be pulled to use it + ;; value should be the same as you print in terminal during pull + :chat-model "llama3:8b-instruct-q8_0" + :embedding-model "nomic-embed-text" + :default-chat-non-standard-params '(("num_ctx" . 8192 ;; Predefined llm providers for interactive switching. ;; You shouldn't add ollama providers here - it can be selected interactively ;; without it. It is just example. @@ -63,14 +64,15 @@ In that case you should customize ellama configuration like this: :embedding-model "mixtral:8x7b-instruct-v0.1-q3_K_M-4k" ;; Naming new sessions with llm (setopt ellama-naming-provider - (make-llm-ollama -:chat-model "mistral:7b-instruct-v0.2-q6_K" -:embedding-model "mistral:7b-instruct-v0.2-q6_K")) + (make-llm-ollama + :chat-model "llama3:8b-instruct-q8_0" + :embedding-model "nomic-embed-text" + :default-chat-non-standard-params '(("stop" . ("\n") (setopt ellama-naming-scheme 'ellama-generate-name-by-llm) ;; Translation llm provider (setopt ellama-translation-provider (make-llm-ollama -:chat-model "sskostyaev/openchat:8k" -:embedding-model "nomic-embed-text"))) + :chat-model "phi3:14b-medium-128k-instruct-q6_K" + :embedding-model "nomic-embed-text"))) #+END_SRC ** Commands
[nongnu] elpa/csv2ledger 574a778a63 121/190: Update README.
branch: elpa/csv2ledger commit 574a778a63728d203cf110fbfa43a3ad88983f7b Author: Joost Kremers Commit: Joost Kremers Update README. --- README.md | 42 -- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 59fab0f8b9..c604ecc879 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,12 @@ The purpose of this small library is to read bank transactions in a CSV file and 2022-20-17 Aldi Supermarket ; Desc: Referenz 999XXX999 ALDI SAGT DANKE Expenses:Groceries -Assets:Checkings -€25.10 +Assets:Checking -€25.10 ``` The description is optional, you can leave it out if you prefer. The format used for the amount is also configurable. By default, `csv2ledger` just copies the amount from the CSV file, but you can apply a conversion to it if you like. -For ease of reference, I will use the following terms to refer to the various parts of the entry. The account associated with the bank account for the CSV file is called the *base* account. In the example here, it is `Assets:Checkings`. The other account, here `Expenses:Groceries`, is the *balancing account*, though I also refer to it as the *target account*. The real-life entity associated with the balancing account, here "Aldi Supermarket" is often called the payee, but since I general [...] +For ease of reference, I will use the following terms to refer to the various parts of the entry. The account associated with the bank account for the CSV file is called the *base* account. In the example here, it is `Assets:Checking`. The other account, here `Expenses:Groceries`, is the *balancing account*, though I also refer to it as the *target account*. The real-life entity associated with the balancing account, here "Aldi Supermarket" is often called the payee, but since I generall [...] Not indicated in the above example is the *effective* date (also called *posted*). This is the date that may follow the booking date, separated by an equal sign: @@ -25,7 +25,7 @@ Not indicated in the above example is the *effective* date (also called *posted* 2022-20-17=2022-20-19 * Aldi Supermarket ; Desc: Referenz 999XXX999 ALDI SAGT DANKE Expenses:Groceries -Assets:Checkings -€25.10 +Assets:Checking -€25.10 ``` If you have this information in your CSV file, you can use it and add it to the entry. If such an effective date is found, the entry is also marked as cleared, i.e., an asterisk appears between the date and the title. @@ -35,8 +35,7 @@ If you have this information in your CSV file, you can use it and add it to the At the very least, you will need to set two user options: `c2l-base-account` and `c2l-csv-columns`. `c2l-base-account` is the account that represents your bank account in your ledger file. By default, it is set to the value `"Assets:Checking"`. - -`c2l-csv-columns` is a list of column labels representing the columns in your CSV file. Note that these column labels should **not** be set to the column names in your CSV file. Rather, they should indicate to `csv2ledger` what type of data each column contains. The following column names are meaningful to `csv2ledger`: +`c2l-csv-columns` is a list of column labels representing the columns in your CSV file. Note that these column labels should **not** be set to the column headers in your CSV file. Rather, they should be symbols indicating to `csv2ledger` what type of data each column contains. The following symbols are meaningful to `csv2ledger`: - `date`: booking date of the transaction - `posted`: effective date of the transaction @@ -46,26 +45,27 @@ At the very least, you will need to set two user options: `c2l-base-account` and - `amount`: the amount of the payment (positive or negative) - `credit`: the amount received - `debit`: the amount payed +- `_` (underscore): ignored column -In the default setup, all these fields may be used to create the Ledger entry, though some of them are only used in specific circumstances. +In the default setup, all these fields (except the underscore, obviously) may be used to create the Ledger entry, though some of them are only used in specific circumstances. Note that `c2l-csv-columns` should contain entries for *all* columns in the CSV file. Columns that you do not use should therefore be indicated with an underscore. -First, `payee` and `sender` never appear both. By default, `payee` is used as the title of the ledger entry and `sender` is ignored. If you set the option `c2l-account-holder` however, the `sender` will be used as the title for transactions in which you are the payee, i.e., when you receive money. If you do not have a `sender` field in your CSV files, you may simply leave it out. In that case, the `payee` wil
[nongnu] elpa/csv2ledger ac0352c3d8 088/190: Set default value of c2l-base-account to "Assets:Checking".
branch: elpa/csv2ledger commit ac0352c3d84f422e56372c531355de5f2ba0a8ce Author: Joost Kremers Commit: Joost Kremers Set default value of c2l-base-account to "Assets:Checking". --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 304361d29c..699ab69bb5 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -47,7 +47,7 @@ can be a separate file or a ledger file containing transactions." :type 'file :group 'csv2ledger) -(defcustom c2l-base-account "Assets:Unknown" +(defcustom c2l-base-account "Assets:Checking" "Base ledger account. A CSV file normally lists transactions for a single bank account. The base ledger account is the ledger account associated with
[nongnu] elpa/csv2ledger 97906fa4ce 016/190: Add user option `c2l-title-function`.
branch: elpa/csv2ledger commit 97906fa4ce50f230795a7520a46207e9a2e1ffc2 Author: Joost Kremers Commit: Joost Kremers Add user option `c2l-title-function`. --- csv2ledger.el | 8 1 file changed, 8 insertions(+) diff --git a/csv2ledger.el b/csv2ledger.el index 8b3ac64f32..56c6ed7230 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -123,6 +123,14 @@ return a string." :type '(repeat (cons (symbol :tag "Field") function)) :group 'csv2ledger) +(defcustom c2l-title-function #'c2l-payee-or-sender + "Function to create a title. +The function should take as argument an entry alist of +field-value pairs and should return a string. The string +returned is used as the title of the ledger entry," + :type 'function + :group 'csv2ledger) + (defun c2l-parse-date (date) "Convert DATE from \"17.10.2022\" to \"2022-10-17\"."
[nongnu] elpa/csv2ledger 3ed3afc06b 025/190: Update doc string of `c2l-csv-entry-as-kill`.
branch: elpa/csv2ledger commit 3ed3afc06b206d2bb67ddb58208df90b4e6851d4 Author: Joost Kremers Commit: Joost Kremers Update doc string of `c2l-csv-entry-as-kill`. --- csv2ledger.el | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 245daddf54..c2c298cd22 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -267,13 +267,9 @@ strings are interpreted according to the template in ;;;###autoload (defun c2l-csv-entry-as-kill () - "Convert the current csv row to a Ledger entry and place it in the kill ring. -The line should have the following format: - -Date Valuation Type Description Sender Payee Amount Balance - -Valuation and Balance are ignored, the other elements are used to -create the ledger entry." + "Convert the current CSV row to a Ledger entry and place it in the kill ring. +The fields in the row are interpreted according to the template +in `c2l-csv-columns'." (interactive) (unless c2l--accounts (setq c2l--accounts (c2l-read-accounts c2l-accounts-file)))
[nongnu] elpa/csv2ledger 3694ef7269 054/190: Small updates to the README.
branch: elpa/csv2ledger commit 3694ef7269dfe4c3a579fa1583dd8e7dd51c009f Author: Joost Kremers Commit: Joost Kremers Small updates to the README. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33b3108210..11b8293a5e 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ A final variable you may want to set is `c2l-alignment-column`. This should most ## Doing the conversion ## -There are three commands to convert CSV lines to ledger entries: `c2l-csv-entry-as-kill` converts the entry point is on and puts the result in the kill ring. It also displays the entry in the echo area so you can see what it is doing. +There are three commands to convert CSV transactions to ledger entries: `c2l-csv-entry-as-kill` converts the line point is on and puts the result in the kill ring. It also displays the entry in the echo area so you can see what it is doing. -The command `c2l-convert-region` and `c2l-convert-buffer` convert the entries in the region or the entire buffer and put the results in a buffer called `*Csv2Ledger Results*`. Each time you call one of these conversion functions, the buffer is cleared, so make sure to save the ledger entries somewhere. You can also simply rename the buffer, Emacs will create a new buffer named `*Csv2Ledger Results*` if it doesn't find an existing one. +The commands `c2l-convert-region` and `c2l-convert-buffer` convert the entries in the region or the entire buffer and put the results in a buffer called `*Csv2Ledger Results*`. Each time you call one of these conversion functions, the buffer is cleared, so make sure to save the ledger entries somewhere. You can also simply rename the buffer, Emacs will create a new buffer named `*Csv2Ledger Results*` if it doesn't find an existing one.
[nongnu] elpa/csv2ledger 33a7db7844 157/190: Fix typo in the README
branch: elpa/csv2ledger commit 33a7db7844723f232f42bfc69f44a690de96db00 Author: Joost Kremers Commit: Joost Kremers Fix typo in the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bd3871f8dd..b588e45f6c 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ Another possible use of `c2l-field-modify-functions` is to make sure the value o ### Modifying the transaction ### -One limitation of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of some other field or fields in the transaction, or if you want to add new fields. If you need to make such a change, you can add a function to the option `c2l-transaction-modify-functions`. This option holds a list of functions that take the entire transaction as its argument and return a mo [...] +One limitation of the functions in `c2l-field-modify-functions` is that they only take the value of a single field as argument. This is insufficient if you want to modify a field value on the basis of some other field or fields in the transaction, or if you want to add new fields. If you need to make such a change, you can add a function to the option `c2l-transaction-modify-functions`. This option holds a list of functions that take the entire transaction as argument and return a modifi [...] The transaction is passed as an alist of field-value pairs, with the fields being symbols and the values being strings. For example, for the ledger entry shown above, the transaction would be as follows:
[nongnu] elpa/csv2ledger 8f23cc044f 145/190: Use `:set` in c2l-account-matchers-file to set c2l-matchers-regexps.
branch: elpa/csv2ledger commit 8f23cc044fc4bc12b9928a5aca5e9191dae05f42 Author: Joost Kremers Commit: Joost Kremers 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 ( . ) conses, where + should be unique but 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 ( . )
[nongnu] elpa/csv2ledger 71e39431eb 078/190: Make c2l-title-function and c2l-amount-function dependent on c2l-csv-columns.
branch: elpa/csv2ledger commit 71e39431eb62331f26e69d98f3fb652f1463c797 Author: Joost Kremers Commit: Joost Kremers Make c2l-title-function and c2l-amount-function dependent on c2l-csv-columns. --- csv2ledger.el | 33 - 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 88efed7ea4..353d415faf 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -79,6 +79,10 @@ instead of the payee as the title of the entry." :type 'string :group 'csv2ledger) +(defun c2l-set-options () + "Set the Csv2Ledger options dependent on `c2l-csv-columns'." + (mapc #'custom-reevaluate-setting '(c2l-amount-function c2l-title-function))) + (defcustom c2l-csv-columns '(date effective description sender payee amount) "List of columns in the CSV file. The data in the CSV file is extracted based on this list. The @@ -107,8 +111,19 @@ It is assumed that a CSV file contains either `payee' and `sender' columns or a `counterpart' column, but not both, and similarly, that it contains either an `amount' column or `credit' and `debit' columns. You should set `c2l-title-function' and -`c2l-amount-function' to match what is valid for your CSV files." +`c2l-amount-function' to match what is valid for your CSV files. + +The options `c2l-title-function' and `c2l-amount-function' are +dependent on the value of this variable. If you update this +variable in your init file without using Customize, make sure to +call `c2l-set-options' to set the dependent variables as well, or +set them directly." :type '(repeat symbol) + :initialize 'custom-initialize-default + :set (lambda (symbol value) + (unless (equal value (eval symbol)) + (custom-set-default symbol value) + (c2l-set-options))) :group 'csv2ledger) (defcustom c2l-field-modify-functions nil @@ -120,21 +135,29 @@ for the field in question." :type '(repeat (cons (symbol :tag "Field") function)) :group 'csv2ledger) -(defcustom c2l-title-function #'c2l-title-is-payee-or-sender +(defcustom c2l-title-function + (if (memq 'counterpart c2l-csv-columns) + #'c2l-title-is-counterpart +#'c2l-title-is-payee-or-sender) "Function to create a title. The function should take as argument an entry alist of field-value pairs and should return a string. The string returned is used as the title of the ledger entry." :type 'function - :group 'csv2ledger) + :group 'csv2ledger + :set-after '(c2l-csv-columns)) -(defcustom c2l-amount-function #'c2l-amount-is-amount +(defcustom c2l-amount-function + (if (memq 'amount c2l-csv-columns) + #'c2l-amount-is-amount +#'c2l-amount-is-credit-or-debit) "Function to create the amount. The function should take as argument an entry alist of field-value pairs and should return a string. The string returned is used as the amount of the ledger entry." :type 'function - :group 'csv2ledger) + :group 'csv2ledger + :set-after '(c2l-csv-columns)) (defcustom c2l-account-matchers-file nil "File containing matcher strings mapped to accounts.
[nongnu] elpa/csv2ledger 6f65342c60 048/190: Update the README.
branch: elpa/csv2ledger commit 6f65342c601b9f0b9410f69457e3fc1f2b557b38 Author: Joost Kremers Commit: Joost Kremers Update the README. --- README.md | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 193ae4078b..e2a3aeb6fd 100644 --- a/README.md +++ b/README.md @@ -46,19 +46,20 @@ These are the two options you must set in order to process any CSV files. There The first of these is `c2l-account-holder`. This should be a string or regular expression that matches your name, whatever your bank puts in the CSV file when you receive money, i.e., when you are the payee. This is used by `csv2ledger` to determine what to use as the title of a transaction. If you are the payee, it uses the sender, otherwise it uses the payee. -Second, you should set `c2l-fallback-account`. This is the account used as the target account when `csv2ledger` cannot determine a target account. This can be, but does not have to be a true ledger account. You can set it to e.g., `"TODO"`, so that after converting a CSV file you can go through the resulting ledger entries and search for the ones where you still need to provide a target account. +Second, you may also want to set `c2l-fallback-account`. This is the account used as the target account when `csv2ledger` cannot determine a target account. This can be, but does not have to be a true ledger account. You can set it to e.g., `"Expenses:TODO"`, so that after converting a CSV file you can go through the resulting ledger entries and search for the ones where you still need to provide a target account. If you do not set `c2l-fallback-account`, conversion of a CSV file will not be entirely automatic: each time `csv2ledger` cannot determine a target account itself (as described below), it will ask you for one. If you prefer this method of operation, leave `c2l-fallback-account` unset. -The option `c2l-accounts-file` can be set to the path of a ledger file containing account declarations. Although `ledger-cli` does not require this, it is good style to define your accounts in a ledger file. Doing so and pointing `c2l-account-file` to it means that whenever `csv2ledger` asks you for an account, it uses completion. +The option `c2l-accounts-file` can be set to the path of a ledger file containing account declarations. Although `ledger-cli` does not require this, it is good style to define your accounts in a ledger file. Doing so and pointing `c2l-account-file` to it means that whenever `csv2ledger` asks you for an account, it offers your accounts for completion, which saves typing and ensures that you don't make typos in your account names.. + +If you have set these options, you are basically good to go. `csv2ledger` will convert a CSV file to ledger entries without complaining. However, you will either have the same target account in each transaction, which is probably not what you want, or Emacs will ask you at every transaction which target account to use. To make this a bit less cumbersome, you can have Emacs try to recognise the target account automatically. -If you have set these options, you are basically good to go. `csv2ledger` will convert a CSV file to ledger entries without complaining. However, target accounts will not be set automatically, so you will either have a lot of correcting to do, or you are being pestered by Emacs at every transaction. ## Automatic target account recognition ## The automatic target account recognition in `csv2ledger` is admittedly fairly simple, but it works well for me. Essentially, it just checks for the presence of certain strings in an entry's fields. Each search string is associated with a ledger account. The first string that is found provides the target account. -To set this up, you first need to create a TSV file containing match strings and ledger accounts: +To set this up, you first need to create a TSV (tab-separated values) file containing match strings and ledger accounts: ``` aldi Expenses:Groceries @@ -66,9 +67,9 @@ lidl Expenses:Groceries restaurantExpenses:Leisure:Restaurant ``` -The first column contains the match strings, the second column the ledger account. There can be multiple match strings associated with one account, as shown in the example. +The first column contains the match strings, the second column the ledger account. There can be multiple match strings associated with one account, as shown in the example. With this file set up, you should point the option `c2l-account-matchers-file` to it so that the matchers can be used to determine the target account. -With this file set up, you should point the option `c2l-account-matchers-file` to it so that the matchers can be used to determine the target account. +What happens is that Emacs looks at the data for a transaction and check if one of the matchers is present in it. This is simple substring matching:
[nongnu] elpa/csv2ledger 8dcb1e208f 073/190: Rework c2l--compose-entry and c2l--csv-line-to-ledger
branch: elpa/csv2ledger commit 8dcb1e208f14ff3fdaec765ba4520e41e8262e77 Author: Joost Kremers Commit: Joost Kremers Rework c2l--compose-entry and c2l--csv-line-to-ledger c2l-compose-entry now only creates the entry, without modifying any of the transaction's values. That work is now done in c2l--csv-line-to-ledger. --- csv2ledger.el | 66 ++- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 1b952fa40a..d779ab99e3 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -253,40 +253,31 @@ make sure to add one using `c2l-field-parse-functions'." (c2l--amount-p (alist-get 'debit transaction "")) "0.00")) -(defun c2l--compose-entry (items &optional from to) ;;; Helper functions (defun c2l--amount-p (str) "Return non-nil is STR is likely to be an amount." (string-match-p "[0-9]+[0-9.,]*[.,][0-9]\\{2\\}" str)) +(defun c2l--compose-entry (transaction) "Create a ledger entry. -ITEMS is an alist containing (key . value) pairs that should be -included in the entry. It should contain values for the keys -`date', `payee', `sender' and `amount'. ITEMS may also contain a -value for `description'. If it is present, it is added as a -comment, preceded by \"Desc:\". - -FROM is the account where the money comes from, TO the account to -which it goes. Note that if AMOUNT is negative, these roles are -reversed. FROM and TO default to `c2l-fallback-account' and -`c2l-base-account', respectively." - (or from (setq from c2l-fallback-account)) - (or to (setq to c2l-base-account)) - (let* ((parsed-items (mapcar (lambda (item) - (let ((field (car item)) - (value (cdr item))) - (cons field - (funcall (alist-get field c2l-field-parse-functions #'identity) value - items)) - (title (funcall c2l-title-function parsed-items))) -(let-alist parsed-items - (concat .date (if .valuation (format "=%s " .valuation) "") (if c2l-auto-cleared " *" "") " " title "\n" - (if (and .description (not (string-empty-p .description))) (format "; Desc: %s\n" .description) "") - (format "%s\n" from) - (format "%s " to) - (make-string (- c2l-alignment-column 4 (length to) 2 (length .amount)) ?\s) - .amount "\n" +TRANSACTION is an alist containing (key . value) pairs that will +be included in the entry. It should at least contain values for +the keys `date', `title', `amount' and `account'. TRANSACTION +may also contain a value for `effective' and `description'. If +`effective' is present, it is added as the effective date for the +entry and the entry is marked as cleared. If `description' is +present, it is added as a comment, preceded by \"Desc:\". If +`c2l-auto-cleared' is non-nil, the entry is always marked as +cleared, even if there is no value for `effective' in +TRANSACTION." + (let-alist transaction +(concat .date (if .effective (format "=%s " .effective) "") (if (or .effective c2l-auto-cleared) " *" "") " " .title "\n" +(if (and .description (not (string-empty-p .description))) (format "; Desc: %s\n" .description) "") +(format "%s\n" .account) +(format "%s " c2l-base-account) +(make-string (- c2l-alignment-column 4 (length c2l-base-account) 2 (length .amount)) ?\s) +.amount "\n"))) (defun c2l--read-accounts (file) "Read list of accounts from FILE." @@ -354,14 +345,25 @@ basis of the matchers in `c2l-account-matchers-file'. If none is found, the value of `c2l-fallback-account' is used. If that option is unset, the user is asked for an account." (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) - (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-balancing-match-fields) fields))) + (parsed-fields (mapcar (lambda (item) + (let ((field (car item)) +(value (cdr item))) +(cons field + (funcall (alist-get field c2l-field-modify-functions #'identity) value +fields)) + (title (funcall c2l-title-function parsed-fields)) + (amount (funcall c2l-amount-function parsed-fields)) + (account (or (-some #'c2l--match-account (mapcar #'cdr (--filter (memq (car it) c2l-balancing-match-fields) parsed-fields))) c2l-fallback-account (completing-read (format "Account for transaction %s, %s «%.75s» " - (funcall c2l-title-function fields) -
[nongnu] main 69e5a9b389: * elpa-packages (csv2ledger): New package
branch: main commit 69e5a9b389738b8f090b96b909a213293cf8e46c Author: Philip Kaludercic Commit: Philip Kaludercic * elpa-packages (csv2ledger): New package --- elpa-packages | 2 ++ 1 file changed, 2 insertions(+) diff --git a/elpa-packages b/elpa-packages index 82dc12718b..d9db9366ef 100644 --- a/elpa-packages +++ b/elpa-packages @@ -115,6 +115,8 @@ :readme "README.md" :news "CHANGELOG.md") + (csv2ledger :url "https://codeberg.org/joostkremers/csv2ledger";) + (cyberpunk-theme :url "https://github.com/n3mo/cyberpunk-theme.el"; :ignored-files ("cyberpunk-theme.png" "example-org-file.org"))
[nongnu] elpa/csv2ledger aaf8db1085 058/190: Make c2l-matcher-regexes public.
branch: elpa/csv2ledger commit aaf8db1085a558a417d8ecb56ae4596504637dea Author: Joost Kremers Commit: Joost Kremers Make c2l-matcher-regexes public. This way, the variable can be used to match the balancing account using regular expressions rather than substrings. The variable is still not a user option, though, because I assume that user that want to set this option won't use Customize. --- csv2ledger.el | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 4ce9a7960a..3557add0a6 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -125,6 +125,17 @@ the corresponding account is used to book the transaction." :type 'file :group 'csv2ledger) +(defvar c2l-matcher-regexes nil + "Alist of accounts and their matchers. +Each item should be a cons cell of an account name and a regular +expression. If the regular expression matches any of the fields +in `c2l-balancing-match-fields', its corresponding account is +used as the balancing 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 regexes to match account.") + (defcustom c2l-balancing-match-fields '(payee description) "List of fields used for determining the balancing account. Fields in this list are matched against the matchers in @@ -148,7 +159,6 @@ This should most likely be set to the same value as :group 'csv2ledger) (defvar c2l--accounts nil "List of ledger accounts, mainly used for completion.") -(defvar c2l--compiled-matcher-regexes nil "Alist of accounts and their matchers.") (defvar c2l--results-buffer nil "Buffer for conversion results.") (defun c2l-convert-little-endian-to-iso8601-date (date) @@ -253,14 +263,14 @@ for that account." (defun c2l--match-account (str) "Try to match STR to an account." - (unless c2l--compiled-matcher-regexes -(setq c2l--compiled-matcher-regexes + (unless c2l-matcher-regexes +(setq c2l-matcher-regexes (-> c2l-account-matchers-file (c2l--read-account-matchers) (c2l--compile-matcher-regexes (--some (if (string-match-p (cdr it) str) (car it)) - c2l--compiled-matcher-regexes)) + c2l-matcher-regexes)) (defun c2l--csv-line-to-ledger (row) "Convert ROW to a ledger entry.
[nongnu] elpa/csv2ledger 0d3a88f8bc 062/190: Rename `valuation` field to `effective`.
branch: elpa/csv2ledger commit 0d3a88f8bc38e44e89faff5173f6e66001a9557d Author: Joost Kremers Commit: Joost Kremers Rename `valuation` field to `effective`. --- csv2ledger.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csv2ledger.el b/csv2ledger.el index 3919f112cf..65ba840e0d 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -79,7 +79,7 @@ instead of the payee as the title of the entry." :type 'string :group 'csv2ledger) -(defcustom c2l-csv-columns '(date valuation description sender payee amount) +(defcustom c2l-csv-columns '(date effective description sender payee amount) "List of columns in the CSV file. The data in the CSV file is extracted based on this list. The order of elements in the list should therefore represent the
[nongnu] elpa/csv2ledger 9dd9708b94 064/190: Rename `c2l-field-parse-functions` to `c2l-field-modify-functions`
branch: elpa/csv2ledger commit 9dd9708b945f3ce9400644b0e490c6366e4c97ca Author: Joost Kremers Commit: Joost Kremers Rename `c2l-field-parse-functions` to `c2l-field-modify-functions` Also update its default value and update the doc string. --- csv2ledger.el | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 976dee5d7e..57b01a21f5 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -111,15 +111,12 @@ and `debit' columns. You should set `c2l-title-function' and :type '(repeat symbol) :group 'csv2ledger) -(defcustom c2l-field-parse-functions '((date. identity) - (valuation . identity) - (description . identity) - (sender . identity) - (payee . identity) - (amount . identity)) +(defcustom c2l-field-modify-functions nil "List of functions to modify fields in an entry. -These functions should take a single string argument and should -return a string." +This option should be an alist mapping field names (as symbols) +to functions. These functions should take a single string +argument and should return a string, which will be the value used +for the field in question." :type '(repeat (cons (symbol :tag "Field") function)) :group 'csv2ledger)
[nongnu] elpa/csv2ledger 982f05c6b9 110/190: Warn and abort if c2l-csv-columns is not set.
branch: elpa/csv2ledger commit 982f05c6b9294e481e618e775ac9f1e10db054b7 Author: Joost Kremers Commit: Joost Kremers Warn and abort if c2l-csv-columns is not set. --- csv2ledger.el | 57 + 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/csv2ledger.el b/csv2ledger.el index 25720b5da4..6409772c88 100644 --- a/csv2ledger.el +++ b/csv2ledger.el @@ -337,38 +337,40 @@ for that account." (cdr it)) c2l-matcher-regexps)) -(defun c2l--csv-line-to-ledger (row) - "Convert ROW to a ledger entry. -ROW contains the data of the entry as a list of strings. The -strings are interpreted according to the template in -`c2l-csv-columns'. The transaction is booked to the account in -`c2l-base-account'. The target account is determined on the -basis of the matchers in `c2l-account-matchers-file'. If none is -found, the value of `c2l-fallback-account' is used. If that -option is unset, the user is asked for an account. - -This function first creates an alist of field-value pairs, -applies the functions in `c2l-field-modify-functions' to the -individual fields and then passes the transaction through +(defun c2l--csv-line-to-ledger (transaction) + "Convert TRANSACTION to a ledger entry. +TRANSACTION is an alist containing the data of the transaction. +The transaction is booked to the account in `c2l-base-account'. +The target account is determined on the basis of the matchers in +`c2l-account-matchers-file'. If none is found, the value of +`c2l-fallback-account' is used. If that option is unset, the +user is asked for an account. + +This function first applies the functions in +`c2l-field-modify-functions' to the individual fields of +TRANSACTION and then passes the transaction through `c2l-transaction-modify-functions' before calling `c2l-entry-function' to create the actual entry." - (let* ((fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) - (modified-fields (mapcar (lambda (item) + (let* ((modified-fields (mapcar (lambda (item) (let ((field (car item)) (value (cdr item))) (cons field (funcall (alist-get field c2l-field-modify-functions #'identity) value - fields)) - (transaction (funcall c2l-transaction-modifier modified-fields))) -(funcall c2l-entry-function transaction))) + transaction)) + (modified-transaction (funcall c2l-transaction-modifier modified-fields))) +(funcall c2l-entry-function modified-transaction))) (defun c2l--get-current-row () "Read the current line as a CSV row. -Return value is a list of values as strings." - (let ((separator (car csv-separator-chars)) -(quote-char (string-to-char (or (car csv-field-quotes) ""))) -(line (buffer-substring-no-properties (point-at-bol) (point-at-eol -(parse-csv-string line separator quote-char))) +Return value is an alist of field-value pairs, where the field +names are taken from `c2l-csv-columns'." + (if c2l-csv-columns + (let* ((separator (car csv-separator-chars)) + (quote-char (string-to-char (or (car csv-field-quotes) ""))) + (line (buffer-substring-no-properties (point-at-bol) (point-at-eol))) + (row (parse-csv-string line separator quote-char))) +(--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row))) +(user-error "Cannot interpret CSV data; set `c2l-csv-columns' first"))) (defun c2l--has-header () "Return non-nil if the current CSV buffer appears to have a header. @@ -377,11 +379,10 @@ Essentially, this function just checks the fields `amount', contains something that looks like a amount." (save-mark-and-excursion (goto-char (point-min)) -(let* ((row (c2l--get-current-row)) - (fields (--remove (eq (car it) '_) (-zip-pair c2l-csv-columns row - (not (or (c2l--amount-p (alist-get 'amount fields "")) - (c2l--amount-p (alist-get 'credit fields "")) - (c2l--amount-p (alist-get 'debit fields ""))) +(let* ((transaction (c2l--get-current-row))) + (not (or (c2l--amount-p (alist-get 'amount transaction "")) + (c2l--amount-p (alist-get 'credit transaction "")) + (c2l--amount-p (alist-get 'debit transaction ""))) (defun c2l--get-results-buffer () "Create a results buffer for conversion.