Merge tag 'v4.0.0'
David Bremner
1 year, 7 months ago
0 | sudo: required | |
1 | language: generic | |
2 | dist: xenial | |
0 | language: nix | |
1 | ||
2 | os: | |
3 | - linux | |
4 | # - osx # Travis is saturated; see https://www.traviscistatus.com/ | |
3 | 5 | |
4 | 6 | env: |
5 | matrix: | |
6 | - EVM_EMACS=emacs-24.3-travis | |
7 | - EVM_EMACS=emacs-25.1-travis | |
8 | # EVM doesn't support xenial yet, which we need since it has ledger version 3. | |
9 | # See https://github.com/rejeep/evm/issues/125 | |
10 | # - EVM_EMACS=emacs-26.1-travis | |
11 | # - EVM_EMACS=emacs-26.2-travis | |
12 | # - EVM_EMACS=emacs-git-snapshot-travis | |
7 | - EMACS_CI=emacs-24-3 LEDGER_VERSION=stable | |
8 | - EMACS_CI=emacs-24-4 LEDGER_VERSION=stable | |
9 | - EMACS_CI=emacs-24-5 LEDGER_VERSION=stable | |
10 | - EMACS_CI=emacs-25-1 LEDGER_VERSION=stable | |
11 | - EMACS_CI=emacs-25-2 LEDGER_VERSION=stable | |
12 | - EMACS_CI=emacs-25-3 LEDGER_VERSION=stable | |
13 | - EMACS_CI=emacs-26-1 LEDGER_VERSION=stable | |
14 | - EMACS_CI=emacs-26-2 LEDGER_VERSION=stable | |
15 | - EMACS_CI=emacs-26-3 LEDGER_VERSION=stable | |
16 | - EMACS_CI=emacs-snapshot LEDGER_VERSION=snapshot | |
13 | 17 | |
14 | before_install: | |
15 | - sudo apt-get install -y ledger | |
16 | - git clone https://github.com/rejeep/evm.git $HOME/.evm | |
17 | - export PATH=$HOME/.evm/bin:$PATH | |
18 | - evm config path /tmp | |
19 | - evm install $EVM_EMACS --use --skip | |
18 | matrix: | |
19 | allow_failures: | |
20 | - env: EMACS_CI=emacs-snapshot LEDGER_VERSION=snapshot | |
21 | ||
22 | install: | |
23 | - bash <(curl https://raw.githubusercontent.com/purcell/nix-emacs-ci/master/travis-install) | |
24 | # TODO: cache builds of this using cachix | |
25 | - nix-env -iA $LEDGER_VERSION -f tools | |
20 | 26 | |
21 | 27 | script: |
22 | 28 | - emacs --version |
23 | 29 | - ledger --version |
24 | - emacs --eval "(setq byte-compile-error-on-warn (>= emacs-major-version 25))" -L . --batch -f batch-byte-compile *.el | |
30 | # Byte compilation is known to fail in Emacs < 26.1 due to ledger-flymake.el, which should | |
31 | # be packaged separately | |
32 | - emacs --eval "(setq byte-compile-error-on-warn (>= emacs-major-version 26))" -L . --batch -f batch-byte-compile *.el | |
25 | 33 | - make -C test test-batch |
26 | 34 | |
27 | 35 | after_script: |
0 | * Development (v4.1) | |
1 | * Release v4.0.0 | |
2 | ** The completion system now respects whatever completion system the user prefers | |
3 | Some users prefer different completion systems such as ivy or helm. To get the | |
4 | old behavior back, see the instructions in the ledger manual under the heading | |
5 | "Adding Transactions." | |
6 | ||
7 | Additionally, we now realign transactions after completion, see | |
8 | ledger-post-auto-align. | |
9 | ** New option ledger-post-auto-align controls whether post amounts automatically align | |
10 | ** New options control whether the report name/command get printed in the report buffer | |
11 | New option ledger-report-use-header-line controls this behavior and | |
12 | ledger-report-header-line-fn controls how the information is reported. | |
13 | ** New option ledger-default-date-format is now used consistently | |
14 | Ledger-mode uses this option to insert dates whenever it is needed. | |
15 | ** Report buffers are now highlighted by ledger | |
16 | So, for example, debts are usually red and deposits blue. | |
17 | ||
18 | New option ledger-report-use-native-highlighting controls this behavior. | |
19 | ||
20 | ** Ledger now matches the width of report buffers | |
21 | Option ledger-report-auto-width controls whether we pass this information to | |
22 | ledger or not. | |
23 | ** Ledger-mode gained support for flymake | |
24 | This supports checking for errors in syntax. | |
25 | ||
26 | Two new options ledger-flymake-be-pedantic and ledger-flymake-be-explicit | |
27 | control which flags get passed to ledger during checking. | |
28 | ** Report windows can be automatically resized | |
29 | See new option ledger-report-resize-window | |
30 | ** All faces used by ledger now inherit from other faces. | |
31 | This should make ledger-mode look better when used with various themes that | |
32 | don't provide support for ledger-mode explicitly. | |
33 | ** New option ledger-report-use-strict controls whether --strict gets passed to reports | |
34 | ** The fontification system (syntax highlighting) was completly rewritten | |
35 | ** In report buffers, M-n and M-p move to the next and previous month | |
36 | See the "Expansion Formats" section of the ledger mode manual to see examples on | |
37 | how to use this. | |
38 | ** New hook ledger-report-after-report-hook runs after the report has been created | |
39 | ** In report buffers, $ toggles converting to the default commodity | |
40 | ** Two new commands move between uncleared transactions | |
41 | New commands ledger-navigate-next-uncleared and | |
42 | ledger-navigate-previous-uncleared move to the next and previous uncleared | |
43 | transactions. These don't have default keybindings. | |
44 | ** New option ledger-accounts-exclude-function | |
45 | This allows users to exclude some accounts from being offered during completion. | |
46 | This is useful if, for example, you have a lot of accounts but only use some of | |
47 | them rarely. |
109 | 109 | (kill-buffer (get-buffer ledger-check-buffer-name))) |
110 | 110 | |
111 | 111 | (defun ledger-check-buffer () |
112 | "Run ledge with --explicit and --strict report errors and assist with fixing them. | |
112 | "Check the current buffer for errors. | |
113 | ||
114 | Runs ledger with --explicit and --strict report errors and assist | |
115 | with fixing them. | |
113 | 116 | |
114 | 117 | The output buffer will be in `ledger-check-mode', which defines |
115 | 118 | commands for navigating the buffer to the errors found, etc." |
135 | 138 | |
136 | 139 | |
137 | 140 | (provide 'ledger-check) |
141 | ||
142 | ;;; ledger-check.el ends here |
109 | 109 | (replace-regexp-in-string char "" str)) |
110 | 110 | |
111 | 111 | (defun ledger-string-to-number (str &optional decimal-comma) |
112 | "improve builtin string-to-number by handling internationalization, and return nil if number can't be parsed" | |
112 | "Parse STR as a number and return that number. | |
113 | ||
114 | Improves builtin `string-to-number' by handling | |
115 | internationalization, and return nil if number can't be parsed. | |
116 | See `ledger-environment-alist' for DECIMAL-COMMA." | |
113 | 117 | (let ((nstr (if (or decimal-comma |
114 | 118 | (assoc "decimal-comma" ledger-environment-alist)) |
115 | 119 | (ledger-strip str "[.]") |
119 | 123 | (string-to-number nstr))) |
120 | 124 | |
121 | 125 | (defun ledger-number-to-string (n &optional decimal-comma) |
122 | "number-to-string that handles comma as decimal." | |
126 | "See `number-to-string' for N. | |
127 | DECIMAL-COMMA is as documented in `ledger-environment-alist'." | |
123 | 128 | (let ((str (number-to-string n))) |
124 | 129 | (when (or decimal-comma |
125 | 130 | (assoc "decimal-comma" ledger-environment-alist)) |
36 | 36 | :type 'file |
37 | 37 | :group 'ledger) |
38 | 38 | |
39 | (defcustom ledger-accounts-exclude-function nil | |
40 | "Function to exclude accounts from completion. | |
41 | Should be a predicate function that accepts one argument, an | |
42 | element of `ledger-accounts-list-in-buffer'." | |
43 | :type 'function | |
44 | :group 'ledger | |
45 | :package-version '(ledger-mode . "2019-08-14")) | |
46 | ||
39 | 47 | (defcustom ledger-complete-in-steps nil |
40 | 48 | "When non-nil, `ledger-complete-at-point' completes account names in steps. |
41 | 49 | If nil, full account names are offered for completion." |
42 | 50 | :type 'boolean |
43 | 51 | :group 'ledger |
44 | :package-version '(ledger-mode . "2019-05-27")) | |
52 | :package-version '(ledger-mode . "4.0.0")) | |
45 | 53 | |
46 | 54 | (defun ledger-parse-arguments () |
47 | 55 | "Parse whitespace separated arguments in the current region." |
89 | 97 | ;; to the list |
90 | 98 | (sort (delete-dups payees-list) #'string-lessp))) |
91 | 99 | |
100 | (defun ledger-accounts-in-buffer () | |
101 | "Return an alist of accounts in the current buffer. | |
102 | The `car' of each element is the account name and the `cdr' is an | |
103 | alist where the key is a subdirective such as \"assert\" and the | |
104 | value (if any) is the associated data. In other words, if you've | |
105 | declared an account like so: | |
106 | ||
107 | account Assets:Checking | |
108 | assert commodity == \"$\" | |
109 | default | |
110 | ||
111 | Then one of the elements this function returns will be | |
112 | \(\"Assets:Checking\" | |
113 | (\"default\") | |
114 | (\"assert\" . \"commodity == \"$\"\"))" | |
115 | (save-excursion | |
116 | (goto-char (point-min)) | |
117 | (let (account-list) | |
118 | ;; First, consider accounts declared with "account" directives, which may or | |
119 | ;; may not have associated data. The data is on the following lines up to a | |
120 | ;; line not starting with whitespace. | |
121 | (while (re-search-forward ledger-account-directive-regex nil t) | |
122 | (let ((account (match-string-no-properties 1)) | |
123 | (lines (buffer-substring-no-properties | |
124 | (point) | |
125 | (progn (ledger-navigate-next-xact-or-directive) | |
126 | (point)))) | |
127 | data) | |
128 | (dolist (d (split-string lines "\n")) | |
129 | (setq d | |
130 | ;; TODO: This is basically (string-trim d) but string-trim | |
131 | ;; doesn't exist in Emacs 24. Replace once we drop Emacs 24. | |
132 | (if (string-match "[[:space:]]+" d) | |
133 | (substring d (match-end 0)) | |
134 | d)) | |
135 | (unless (string= d "") | |
136 | (if (string-match " " d) | |
137 | (push (cons (substring d 0 (match-beginning 0)) | |
138 | (substring d (match-end 0) nil)) | |
139 | data) | |
140 | (push (cons d nil) data)))) | |
141 | (push (cons account data) account-list))) | |
142 | ;; Next, gather all accounts declared in postings | |
143 | (unless | |
144 | ;; FIXME: People who have set `ledger-flymake-be-pedantic' to non-nil | |
145 | ;; probably don't want accounts from postings, just those declared | |
146 | ;; with directives. But the name is a little misleading. Should we | |
147 | ;; make a ledger-mode-be-pedantic and use that instead? | |
148 | (bound-and-true-p ledger-flymake-be-pedantic) | |
149 | (goto-char (point-min)) | |
150 | (while (re-search-forward ledger-account-name-or-directive-regex nil t) | |
151 | (let ((account (match-string-no-properties 1))) | |
152 | (unless (member account (mapcar #'car account-list)) | |
153 | (push (cons account nil) account-list))))) | |
154 | (sort account-list (lambda (a b) (string-lessp (car a) (car b))))))) | |
155 | ||
92 | 156 | (defun ledger-accounts-list-in-buffer () |
93 | 157 | "Return a list of all known account names in the current buffer as strings. |
94 | 158 | Considers both accounts listed in postings and those declared with \"account\" directives." |
95 | (save-excursion | |
96 | (goto-char (point-min)) | |
97 | (let (results) | |
98 | (while (re-search-forward ledger-account-name-or-directive-regex nil t) | |
99 | (setq results (cons (match-string-no-properties 1) results))) | |
100 | (sort (delete-dups results) #'string-lessp)))) | |
159 | (let ((accounts (ledger-accounts-in-buffer))) | |
160 | (when ledger-accounts-exclude-function | |
161 | (setq accounts (cl-remove-if ledger-accounts-exclude-function accounts))) | |
162 | (mapcar #'car accounts))) | |
101 | 163 | |
102 | 164 | (defun ledger-accounts-list () |
103 | 165 | "Return a list of all known account names as strings. |
232 | 294 | (eq (save-excursion (ledger-thing-at-point)) 'transaction) |
233 | 295 | (setq start (save-excursion (backward-word) (point))) |
234 | 296 | (setq collection #'ledger-payees-in-buffer)) |
235 | ((looking-back (rx-to-string `(seq bol (one-or-more space) (group (zero-or-more (not space))))) (line-beginning-position)) | |
297 | (;; Accounts | |
298 | (looking-back (rx-to-string `(seq bol (one-or-more space) (group (zero-or-more (not space))))) (line-beginning-position)) | |
236 | 299 | (setq start (match-beginning 1) |
237 | 300 | delete-suffix (save-excursion |
238 | 301 | (when (search-forward-regexp (rx (or eol (repeat 2 space))) (line-end-position) t) |
260 | 323 | (replace-regexp-in-string "[ \t]*$" "" str)) |
261 | 324 | |
262 | 325 | (defun ledger-fully-complete-xact () |
263 | "Completes a transaction if there is another matching payee in the buffer. | |
264 | Does not use ledger xact" | |
326 | "Completes a transaction if there is another matching payee in the buffer." | |
265 | 327 | (interactive) |
328 | (unless (looking-back ledger-payee-any-status-regex (line-beginning-position)) | |
329 | (user-error "Point is not after payee")) | |
266 | 330 | (let* ((name (ledger-trim-trailing-whitespace (caar (ledger-parse-arguments)))) |
267 | 331 | (rest-of-name name) |
268 | 332 | xacts) |
276 | 340 | (setq rest-of-name (match-string 3)) |
277 | 341 | ;; Start copying the postings |
278 | 342 | (forward-line) |
279 | (while (looking-at ledger-account-any-status-regex) | |
280 | (setq xacts (cons (buffer-substring-no-properties | |
281 | (line-beginning-position) | |
282 | (line-end-position)) | |
283 | xacts)) | |
284 | (forward-line)) | |
285 | (setq xacts (nreverse xacts))))) | |
343 | (setq xacts (buffer-substring-no-properties (point) (ledger-navigate-end-of-xact)))))) | |
286 | 344 | ;; Insert rest-of-name and the postings |
287 | (when xacts | |
288 | (save-excursion | |
289 | (insert rest-of-name ?\n) | |
290 | (while xacts | |
291 | (insert (car xacts) ?\n) | |
292 | (setq xacts (cdr xacts)))) | |
293 | (forward-line) | |
294 | (goto-char (line-end-position)) | |
295 | (if (re-search-backward "\\(\t\\| [ \t]\\)" nil t) | |
296 | (goto-char (match-end 0)))))) | |
345 | (save-excursion | |
346 | (insert rest-of-name ?\n) | |
347 | (insert xacts) | |
348 | (insert ?\n)) | |
349 | (forward-line) | |
350 | (goto-char (line-end-position)) | |
351 | (when (re-search-backward "\\(\t\\| [ \t]\\)" nil t) | |
352 | (goto-char (match-end 0))))) | |
297 | 353 | |
298 | 354 | (provide 'ledger-complete) |
299 | 355 |
52 | 52 | (concat (apply 'concat (mapcar 'ledger-get-regex-str elements)) "[ \t]*$")) |
53 | 53 | |
54 | 54 | (defmacro ledger-single-line-config (&rest elements) |
55 | "Take list of ELEMENTS and return regex and element list for use in context-at-point" | |
55 | "Take list of ELEMENTS and return regex and element list for use in context-at-point." | |
56 | 56 | `(list (ledger-line-regex (quote ,elements)) (quote ,elements))) |
57 | 57 | |
58 | 58 | (defconst ledger-line-config |
39 | 39 | If --pedantic is in your ledgerrc file, then --pedantic gets |
40 | 40 | passed regardless of the value." |
41 | 41 | :type 'boolean |
42 | :package-version '(ledger-mode . "4.0.0") | |
42 | 43 | :group 'ledger) |
43 | 44 | |
44 | 45 | (defcustom ledger-flymake-be-explicit nil |
46 | 47 | If --explicit is in your ledgerrc file, then --explicit gets |
47 | 48 | passed regardless of the value." |
48 | 49 | :type 'boolean |
50 | :package-version '(ledger-mode . "4.0.0") | |
49 | 51 | :group 'ledger) |
50 | 52 | |
51 | 53 | ;; Based on the example from Flymake's info: |
456 | 456 | "Construct anchored highlighters for subdirectives. |
457 | 457 | |
458 | 458 | Each element of SUBDIRECTIVES should have the form (MATCHER |
459 | SUBEXP-HIGHLIGHTERS…). The result will be a list of elements of | |
459 | SUBEXP-HIGHLIGHTERS…). The result will be a list of elements of | |
460 | 460 | the form (MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS) with |
461 | 461 | PRE-FORM and POST-FORM set to appropriate values. |
462 | 462 |
41 | 41 | Set this to the value of `ledger-iso-date-format' if you prefer |
42 | 42 | ISO 8601 dates." |
43 | 43 | :type 'string |
44 | :package-version '(ledger-mode . "4.0.0") | |
44 | 45 | :group 'ledger) |
45 | 46 | |
46 | 47 | (defconst ledger-iso-date-format "%Y-%m-%d" |
100 | 100 | (org-read-date nil t nil prompt)))) |
101 | 101 | |
102 | 102 | (defun ledger-get-minibuffer-prompt (prompt default) |
103 | "Return a string composing of PROMPT and DEFAULT appropriate | |
104 | for a minibuffer prompt." | |
103 | "Return a string composing of PROMPT and DEFAULT appropriate for a minibuffer prompt." | |
105 | 104 | (concat prompt |
106 | 105 | (if default |
107 | 106 | (concat " (" default "): ") |
108 | 107 | ": "))) |
109 | 108 | |
110 | 109 | (defun ledger-completing-read-with-default (prompt default collection) |
111 | "Return a user supplied string after PROMPT, or DEFAULT while | |
112 | providing completions from COLLECTION." | |
110 | "Return a user supplied string after PROMPT, or DEFAULT while providing completions from COLLECTION." | |
113 | 111 | (completing-read (ledger-get-minibuffer-prompt prompt default) |
114 | 112 | collection nil nil nil 'ledger-minibuffer-history default)) |
115 | 113 | |
122 | 120 | "Display the cleared-or-pending balance. |
123 | 121 | And calculate the target-delta of the account being reconciled. |
124 | 122 | |
125 | With prefix argument \\[universal-argument] ask for the target commodity and convert | |
123 | With ARG (\\[universal-argument]) ask for the target commodity and convert | |
126 | 124 | the balance into that." |
127 | 125 | (interactive "P") |
128 | 126 | (let* ((account (ledger-read-account-with-prompt "Account balance to show")) |
55 | 55 | "When non-nil, realign post amounts when indenting or completing." |
56 | 56 | :type 'boolean |
57 | 57 | :group 'ledger-post |
58 | :package-version '(ledger-mode . "4.0.0") | |
58 | 59 | :safe 'booleanp) |
59 | 60 | |
60 | 61 | (defun ledger-next-amount (&optional end) |
128 | 129 | (defun ledger-indent-line () |
129 | 130 | "Indent the current line." |
130 | 131 | ;; Ensure indent if the previous line was indented |
131 | (let ((indent-level (save-excursion (if (progn (when (zerop (forward-line -1)) | |
132 | (memq (ledger-thing-at-point) '(transaction posting)))) | |
132 | (let ((indent-level (save-excursion (if (and (zerop (forward-line -1)) | |
133 | (memq (ledger-thing-at-point) '(transaction posting))) | |
133 | 134 | ledger-post-account-alignment-column |
134 | 135 | 0)))) |
135 | 136 | (unless (= (current-indentation) indent-level) |
58 | 58 | :group 'ledger-reconcile) |
59 | 59 | |
60 | 60 | (defcustom ledger-buffer-tracks-reconcile-buffer t |
61 | "If t, then when the cursor is moved to a new transaction in the reconcile buffer. | |
62 | Then that transaction will be shown in its source buffer." | |
61 | "If t, move point in the ledger buffer when it moves in the reconcile buffer. | |
62 | When the cursor is moved to a new transaction in the reconcile | |
63 | buffer then that transaction will be shown in its source buffer." | |
63 | 64 | :type 'boolean |
64 | 65 | :group 'ledger-reconcile) |
65 | 66 | |
76 | 77 | |
77 | 78 | (defcustom ledger-reconcile-default-date-format ledger-default-date-format |
78 | 79 | "Date format for the reconcile buffer. |
79 | Default is ledger-default-date-format." | |
80 | Default is `ledger-default-date-format'." | |
80 | 81 | :type 'string |
81 | 82 | :group 'ledger-reconcile) |
82 | 83 | |
100 | 101 | preced by a minus sign which mean to left justify and pad the |
101 | 102 | field. WIDTH is the minimum number of characters to display; |
102 | 103 | if string is longer, it is not truncated unless |
103 | ledger-reconcile-buffer-payee-max-chars or | |
104 | ledger-reconcile-buffer-account-max-chars is defined." | |
104 | `ledger-reconcile-buffer-payee-max-chars' or | |
105 | `ledger-reconcile-buffer-account-max-chars' is defined." | |
105 | 106 | :type 'string |
106 | 107 | :group 'ledger-reconcile) |
107 | 108 | |
510 | 511 | (pop-to-buffer rbuf))) |
511 | 512 | |
512 | 513 | (defun ledger-reconcile-check-valid-account (account) |
513 | "Check to see if ACCOUNT exists in the ledger file" | |
514 | "Check to see if ACCOUNT exists in the ledger file." | |
514 | 515 | (if (> (length account) 0) |
515 | 516 | (save-excursion |
516 | 517 | (goto-char (point-min)) |
517 | 518 | (search-forward account nil t)))) |
518 | 519 | |
519 | 520 | (defun ledger-reconcile (&optional account target) |
520 | "Start reconciling, prompt for account." | |
521 | "Start reconciling, prompt for ACCOUNT." | |
521 | 522 | (interactive) |
522 | 523 | (let ((account (or account (ledger-read-account-with-prompt "Account to reconcile"))) |
523 | 524 | (buf (current-buffer)) |
559 | 560 | (defvar ledger-reconcile-mode-abbrev-table) |
560 | 561 | |
561 | 562 | (defun ledger-reconcile-change-target (&optional target) |
562 | "Change the target amount for the reconciliation process." | |
563 | "Change the TARGET amount for the reconciliation process." | |
563 | 564 | (interactive) |
564 | 565 | (setq ledger-target (or target (ledger-read-commodity-string ledger-reconcile-target-prompt-string)))) |
565 | 566 |
17 | 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
18 | 18 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
19 | 19 | ;; MA 02110-1301 USA. |
20 | ||
21 | ||
22 | ;;; Commentary: | |
23 | ;; Regular expressions used by ledger-mode. | |
24 | ||
25 | ;;; Code: | |
20 | 26 | |
21 | 27 | (require 'rx) |
22 | 28 | (require 'cl-lib) |
403 | 409 | |
404 | 410 | |
405 | 411 | (provide 'ledger-regex) |
412 | ||
413 | ;;; ledger-regex.el ends here |
97 | 97 | (defcustom ledger-report-use-native-highlighting t |
98 | 98 | "When non-nil, use ledger's native highlighting in reports." |
99 | 99 | :type 'boolean |
100 | :package-version '(ledger-mode . "4.0.0") | |
100 | 101 | :group 'ledger-report) |
101 | 102 | |
102 | 103 | (defcustom ledger-report-auto-width t |
103 | 104 | "When non-nil, tell ledger about the width of the report window." |
104 | 105 | :type 'boolean |
106 | :package-version '(ledger-mode . "4.0.0") | |
105 | 107 | :group 'ledger-report) |
106 | 108 | |
107 | 109 | (defcustom ledger-report-use-header-line nil |
110 | 112 | `ledger-report-header-line-fn' for how to customize the |
111 | 113 | information reported." |
112 | 114 | :type 'boolean |
115 | :package-version '(ledger-mode . "4.0.0") | |
113 | 116 | :group 'ledger-report) |
114 | 117 | |
115 | 118 | (defcustom ledger-report-header-line-fn #'ledger-report--header-function |
116 | 119 | "Evaluate this function in the `header-line' of the report buffer. |
117 | 120 | `ledger-report-use-header-line' must be non-nil for this to have any effect." |
118 | 121 | :type 'function |
122 | :package-version '(ledger-mode . "4.0.0") | |
119 | 123 | :group 'ledger-report) |
120 | 124 | |
121 | 125 | (defcustom ledger-report-resize-window t |
122 | 126 | "If non-nil, resize the report window. |
123 | 127 | Calls `shrink-window-if-larger-than-buffer'." |
124 | 128 | :type 'boolean |
129 | :package-version '(ledger-mode . "4.0.0") | |
125 | 130 | :group 'ledger-report) |
126 | 131 | |
127 | 132 | (defcustom ledger-report-use-strict nil |
128 | "Should Ledger-mode pass --strict as a command line parameter | |
129 | when running reports?" | |
130 | :type 'boolean | |
133 | "When non-nil, `ledger-mode' will use --strict when running reports?" | |
134 | :type 'boolean | |
135 | :package-version '(ledger-mode . "4.0.0") | |
131 | 136 | :group 'ledger-report) |
132 | 137 | |
133 | 138 | (defcustom ledger-report-after-report-hook nil |
134 | 139 | "Hook run after `ledger-report' has created the buffer and report." |
135 | 140 | :type 'boolean |
141 | :package-version '(ledger-mode . "4.0.0") | |
136 | 142 | :group 'ledger-report) |
137 | 143 | |
138 | 144 | (defvar ledger-report-buffer-name "*Ledger Report*") |
179 | 185 | (define-key map [?r] #'ledger-report-redo) |
180 | 186 | (define-key map [(shift ?r)] #'ledger-report-reverse-report) |
181 | 187 | (define-key map [?s] #'ledger-report-save) |
182 | (define-key map [(shift ?s)] #'ledger-report-select-report) | |
188 | (define-key map [(shift ?s)] #'ledger-report) | |
183 | 189 | (define-key map [?e] #'ledger-report-edit-report) |
184 | 190 | (define-key map [( shift ?e)] #'ledger-report-edit-reports) |
185 | 191 | (define-key map [?q] #'ledger-report-quit) |
200 | 206 | (easy-menu-define ledger-report-mode-menu ledger-report-mode-map |
201 | 207 | "Ledger report menu" |
202 | 208 | '("Reports" |
203 | ["Select Report" ledger-report-select-report] | |
209 | ["Select Report" ledger-report] | |
204 | 210 | ["Save Report" ledger-report-save] |
205 | 211 | ["Edit Current Report" ledger-report-edit-report] |
206 | 212 | ["Edit All Reports" ledger-report-edit-reports] |
216 | 222 | )) |
217 | 223 | |
218 | 224 | (define-derived-mode ledger-report-mode special-mode "Ledger-Report" |
219 | "A mode for viewing ledger reports.") | |
225 | "A mode for viewing ledger reports." | |
226 | (hack-dir-local-variables-non-file-buffer)) | |
220 | 227 | |
221 | 228 | (defconst ledger-report--extra-args-marker "[[ledger-mode-flags]]") |
222 | 229 | |
467 | 474 | 'action (lambda (_button) (ledger-report-visit-source))) |
468 | 475 | |
469 | 476 | (defun ledger-report--change-month (shift) |
470 | "Rebuild report with transactions from current month + shift." | |
477 | "Rebuild report with transactions from current month + SHIFT." | |
471 | 478 | (let* ((current-month (or ledger-report-current-month (ledger-report--current-month))) |
472 | 479 | (previous-month (ledger-report--shift-month current-month shift))) |
473 | 480 | (set (make-local-variable 'ledger-report-current-month) previous-month) |
480 | 487 | (let ((file (match-string 1)) |
481 | 488 | (line (string-to-number (match-string 2)))) |
482 | 489 | (delete-region (match-beginning 0) (match-end 0)) |
483 | (when file | |
490 | (when (and file line) | |
484 | 491 | (add-text-properties (line-beginning-position) (line-end-position) |
485 | (list 'ledger-source (cons file (save-window-excursion | |
486 | (save-excursion | |
487 | (find-file file) | |
488 | (widen) | |
489 | (ledger-navigate-to-line line) | |
490 | (point-marker)))))) | |
492 | (list 'ledger-source (cons file line))) | |
491 | 493 | (make-text-button |
492 | 494 | (line-beginning-position) (line-end-position) |
493 | 495 | 'type 'ledger-report-register-entry |
536 | 538 | "Visit the transaction under point in the report window." |
537 | 539 | (interactive) |
538 | 540 | (let* ((prop (get-text-property (point) 'ledger-source)) |
539 | (file (if prop (car prop))) | |
540 | (line-or-marker (if prop (cdr prop)))) | |
541 | (when (and file line-or-marker) | |
541 | (file (car prop)) | |
542 | (line (cdr prop))) | |
543 | (when (and file line) | |
542 | 544 | (find-file-other-window file) |
543 | 545 | (widen) |
544 | (if (markerp line-or-marker) | |
545 | (goto-char line-or-marker) | |
546 | (goto-char (point-min)) | |
547 | (forward-line (1- line-or-marker)) | |
548 | (re-search-backward "^[0-9]+") | |
549 | (beginning-of-line) | |
550 | (let ((start-of-txn (point))) | |
551 | (forward-paragraph) | |
552 | (narrow-to-region start-of-txn (point)) | |
553 | (backward-paragraph)))))) | |
546 | (goto-char (point-min)) | |
547 | (forward-line (1- line)) | |
548 | (ledger-navigate-beginning-of-xact)))) | |
554 | 549 | |
555 | 550 | (defun ledger-report-goto () |
556 | 551 | "Goto the ledger report buffer." |
601 | 596 | (setq ledger-report-cmd (ledger-report-read-command ledger-report-cmd)) |
602 | 597 | (ledger-report-redo)) |
603 | 598 | |
604 | (defun ledger-report-select-report () | |
605 | "Select and run one of the named reports." | |
606 | (interactive) | |
607 | (setq ledger-report-name (ledger-report-read-name) | |
608 | ledger-report-cmd (ledger-report-cmd ledger-report-name nil)) | |
609 | (ledger-report-redo)) | |
599 | (define-obsolete-function-alias 'ledger-report-select-report #'ledger-report "ledger 4.0.0") | |
610 | 600 | |
611 | 601 | (defun ledger-report-read-new-name () |
612 | 602 | "Read the name for a new report from the minibuffer." |
67 | 67 | ("Fr" 5) |
68 | 68 | ("Sa" 6) |
69 | 69 | ("Su" 0)) |
70 | "List of weekday abbreviations. There must be exactly seven | |
71 | entries each with a two character abbreviation for a day and the | |
72 | number of that day in the week. " | |
70 | "List of weekday abbreviations. | |
71 | There must be exactly seven entries each with a two character | |
72 | abbreviation for a day and the number of that day in the week." | |
73 | 73 | :type '(alist :value-type (group integer)) |
74 | 74 | :group 'ledger-schedule) |
75 | 75 | |
211 | 211 | (defun ledger-schedule-constrain-year (year-desc month-desc day-desc) |
212 | 212 | "Return a form that constrains the year. |
213 | 213 | |
214 | YEAR-DESC, MONT-DESC, and DAY-DESC are the string portions of the | |
214 | YEAR-DESC, MONTH-DESC, and DAY-DESC are the string portions of the | |
215 | 215 | date descriptor." |
216 | 216 | (cond |
217 | 217 | ((string-match "[A-Za-z]" day-desc) t) ; there is an advanced day descriptor which overrides the year |
224 | 224 | (defun ledger-schedule-constrain-month (year-desc month-desc day-desc) |
225 | 225 | "Return a form that constrains the month. |
226 | 226 | |
227 | YEAR-DESC, MONT-DESC, and DAY-DESC are the string portions of the | |
227 | YEAR-DESC, MONTH-DESC, and DAY-DESC are the string portions of the | |
228 | 228 | date descriptor." |
229 | 229 | (cond |
230 | 230 | ((string-match "[A-Za-z]" day-desc) t) ; there is an advanced day descriptor which overrides the month |
242 | 242 | (defun ledger-schedule-constrain-day (year-desc month-desc day-desc) |
243 | 243 | "Return a form that constrains the day. |
244 | 244 | |
245 | YEAR-DESC, MONT-DESC, and DAY-DESC are the string portions of the | |
245 | YEAR-DESC, MONTH-DESC, and DAY-DESC are the string portions of the | |
246 | 246 | date descriptor." |
247 | 247 | (cond ((string= day-desc "*") |
248 | 248 | t) |
17 | 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
18 | 18 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
19 | 19 | ;; MA 02110-1301 USA. |
20 | ||
21 | ;;; Commentary: | |
22 | ;; | |
23 | ||
20 | 24 | ;;; Code: |
21 | 25 | (defvar ledger-binary-path) |
22 | 26 | |
25 | 29 | :group 'ledger) |
26 | 30 | |
27 | 31 | (defcustom ledger-texi-sample-doc-path "~/ledger/doc/sample.dat" |
28 | "Location for sample data to be used in texi tests" | |
32 | "Location for sample data to be used in texi tests." | |
29 | 33 | :type 'file |
30 | 34 | :group 'ledger-texi) |
31 | 35 | |
32 | 36 | (defcustom ledger-texi-normalization-args "--args-only --columns 80" |
33 | "texi normalization for producing ledger output" | |
37 | "Texi normalization for producing ledger output." | |
34 | 38 | :type 'string |
35 | 39 | :group 'ledger-texi) |
36 | 40 | |
170 | 174 | "../test/manual"))))) |
171 | 175 | |
172 | 176 | (provide 'ledger-texi) |
177 | ||
178 | ;;; ledger-texi.el ends here |
163 | 163 | (list |
164 | 164 | "Expenses:The Bakery")))))) |
165 | 165 | |
166 | (ert-deftest ledger-complete/test-ledger-accounts-exclude-function () | |
167 | ;; TODO: Why doesn't this work in batch? | |
168 | :tags '(interactive) | |
169 | (with-temp-buffer | |
170 | (insert "account Assets:Checking:Bank A | |
171 | assert date<=[1990-01-01] | |
172 | account Assets:Checking:Bank B") | |
173 | (let ((ledger-accounts-exclude-function | |
174 | (lambda (i) "Exclude all entries with a subdirective." | |
175 | (cdr i)))) | |
176 | (should (equal (ledger-accounts-list-in-buffer) | |
177 | (list "Assets:Checking:Bank B")))) | |
178 | (let ((ledger-accounts-exclude-function (lambda (_) t))) | |
179 | (should (equal (ledger-accounts-list-in-buffer) | |
180 | nil))) | |
181 | (let ((ledger-accounts-exclude-function (lambda (_) nil))) | |
182 | (should (equal (ledger-accounts-list-in-buffer) | |
183 | (list "Assets:Checking:Bank A" | |
184 | "Assets:Checking:Bank B")))))) | |
185 | ||
166 | 186 | (provide 'complete-test) |
167 | 187 | |
168 | 188 | ;;; complete-test.el ends here |
0 | { pkgs ? import <nixpkgs> {} }: | |
1 | ||
2 | let | |
3 | ledgerFromGit = builtins.fetchGit { url = git://github.com/ledger/ledger; }; | |
4 | in | |
5 | { | |
6 | stable = pkgs.ledger; | |
7 | ||
8 | snapshot = (pkgs.callPackage ledgerFromGit {}) | |
9 | .overrideAttrs(a: { | |
10 | doCheck = false; | |
11 | cmakeFlags = a.cmakeFlags ++ [ "-DCMAKE_INSTALL_MANDIR=share/man" ]; | |
12 | }); | |
13 | } |