123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- ;;; ledger-reconcile.el --- Helper code for use with the "ledger" command-line tool
- ;; Copyright (C) 2003-2016 John Wiegley (johnw AT gnu DOT org)
- ;; This file is not part of GNU Emacs.
- ;; This is free software; you can redistribute it and/or modify it under
- ;; the terms of the GNU General Public License as published by the Free
- ;; Software Foundation; either version 2, or (at your option) any later
- ;; version.
- ;;
- ;; This is distributed in the hope that it will be useful, but WITHOUT
- ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- ;; for more details.
- ;;
- ;; You should have received a copy of the GNU General Public License
- ;; along with GNU Emacs; see the file COPYING. If not, write to the
- ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- ;; MA 02110-1301 USA.
- ;; Reconcile mode
- ;;; Commentary:
- ;; Code to handle reconciling Ledger files wiht outside sources
- ;;; Code:
- (require 'easymenu)
- (require 'ledger-init)
- (defvar ledger-buf nil)
- (defvar ledger-bufs nil)
- (defvar ledger-acct nil)
- (defvar ledger-target nil)
- (defgroup ledger-reconcile nil
- "Options for Ledger-mode reconciliation"
- :group 'ledger)
- (defcustom ledger-recon-buffer-name "*Reconcile*"
- "Name to use for reconciliation buffer."
- :group 'ledger-reconcile)
- (defcustom ledger-narrow-on-reconcile t
- "If t, limit transactions shown in main buffer to those matching the reconcile regex."
- :type 'boolean
- :group 'ledger-reconcile)
- (defcustom ledger-buffer-tracks-reconcile-buffer t
- "If t, then when the cursor is moved to a new transaction in the reconcile buffer.
- Then that transaction will be shown in its source buffer."
- :type 'boolean
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-force-window-bottom nil
- "If t, make the reconcile window appear along the bottom of the register window and resize."
- :type 'boolean
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-toggle-to-pending t
- "If t, then toggle between uncleared and pending.
- reconcile-finish will mark all pending posting cleared."
- :type 'boolean
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-default-date-format ledger-default-date-format
- "Date format for the reconcile buffer.
- Default is ledger-default-date-format."
- :type 'string
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-target-prompt-string "Target amount for reconciliation "
- "Prompt for recon target."
- :type 'string
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-buffer-header "Reconciling account %s\n\n"
- "Default header string for the reconcile buffer.
- If non-nil, the name of the account being reconciled will be substituted
- into the '%s'. If nil, no header will be displayed."
- :type 'string
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-buffer-line-format "%(date)s %-4(code)s %-50(payee)s %-30(account)s %15(amount)s\n"
- "Format string for the ledger reconcile posting format.
- Available fields are date, status, code, payee, account,
- amount. The format for each field is %WIDTH(FIELD), WIDTH can be
- preced by a minus sign which mean to left justify and pad the
- field. WIDTH is the minimum number of characters to display;
- if string is longer, it is not truncated unless
- ledger-reconcile-buffer-payee-max-chars or
- ledger-reconcile-buffer-account-max-chars is defined."
- :type 'string
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-buffer-payee-max-chars -1
- "If positive, truncate payee name right side to max number of characters."
- :type 'integer
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-buffer-account-max-chars -1
- "If positive, truncate account name left side to max number of characters."
- :type 'integer
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-sort-key "(0)"
- "Key for sorting reconcile buffer.
- Possible values are '(date)', '(amount)', '(payee)' or '(0)' for no sorting, i.e. using ledger file order."
- :type 'string
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-insert-effective-date nil
- "If t, prompt for effective date when clearing transactions during reconciliation."
- :type 'boolean
- :group 'ledger-reconcile)
- (defcustom ledger-reconcile-finish-force-quit nil
- "If t, will force closing reconcile window after \\[ledger-reconcile-finish]."
- :type 'boolean
- :group 'ledger-reconcile)
- ;; s-functions below are copied from Magnars' s.el
- ;; prefix ledger-reconcile- is added to not conflict with s.el
- (defun ledger-reconcile-s-pad-left (len padding s)
- "If S is shorter than LEN, pad it with PADDING on the left."
- (let ((extra (max 0 (- len (length s)))))
- (concat (make-string extra (string-to-char padding))
- s)))
- (defun ledger-reconcile-s-pad-right (len padding s)
- "If S is shorter than LEN, pad it with PADDING on the right."
- (let ((extra (max 0 (- len (length s)))))
- (concat s
- (make-string extra (string-to-char padding)))))
- (defun ledger-reconcile-s-left (len s)
- "Return up to the LEN first chars of S."
- (if (> (length s) len)
- (substring s 0 len)
- s))
- (defun ledger-reconcile-s-right (len s)
- "Return up to the LEN last chars of S."
- (let ((l (length s)))
- (if (> l len)
- (substring s (- l len) l)
- s)))
- (defun ledger-reconcile-truncate-right (str len)
- "Truncate STR right side with max LEN characters, and pad with '…' if truncated."
- (if (and (>= len 0) (> (length str) len))
- (ledger-reconcile-s-pad-right len "…" (ledger-reconcile-s-left (- len 1) str))
- str))
- (defun ledger-reconcile-truncate-left (str len)
- "Truncate STR left side with max LEN characters, and pad with '…' if truncated."
- (if (and (>= len 0) (> (length str) len))
- (ledger-reconcile-s-pad-left len "…" (ledger-reconcile-s-right (- len 1) str))
- str))
- (defun ledger-reconcile-get-cleared-or-pending-balance (buffer account)
- "Use BUFFER to Calculate the cleared or pending balance of the ACCOUNT."
- ;; these vars are buffer local, need to hold them for use in the
- ;; temp buffer below
- (with-temp-buffer
- ;; note that in the line below, the --format option is
- ;; separated from the actual format string. emacs does not
- ;; split arguments like the shell does, so you need to
- ;; specify the individual fields in the command line.
- (if (ledger-exec-ledger buffer (current-buffer)
- "balance" "--limit" "cleared or pending" "--empty" "--collapse"
- "--format" "%(scrub(display_total))" account)
- (ledger-split-commodity-string
- (buffer-substring-no-properties (point-min) (point-max))))))
- (defun ledger-display-balance ()
- "Display the cleared-or-pending balance.
- And calculate the target-delta of the account being reconciled."
- (interactive)
- (let* ((pending (ledger-reconcile-get-cleared-or-pending-balance ledger-buf ledger-acct)))
- (when pending
- (if ledger-target
- (message "Cleared and Pending balance: %s, Difference from target: %s"
- (ledger-commodity-to-string pending)
- (ledger-commodity-to-string (-commodity ledger-target pending)))
- (message "Pending balance: %s"
- (ledger-commodity-to-string pending))))))
- (defun ledger-is-stdin (file)
- "True if ledger FILE is standard input."
- (or
- (equal file "")
- (equal file "<stdin>")
- (equal file "/dev/stdin")))
- (defun ledger-reconcile-get-buffer (where)
- "Return a buffer from WHERE the transaction is."
- (if (bufferp (car where))
- (car where)
- (error "Function ledger-reconcile-get-buffer: Buffer not set")))
- (defun ledger-reconcile-toggle ()
- "Toggle the current transaction, and mark the recon window."
- (interactive)
- (beginning-of-line)
- (let ((where (get-text-property (point) 'where))
- (inhibit-read-only t)
- status)
- (when (ledger-reconcile-get-buffer where)
- (with-current-buffer (ledger-reconcile-get-buffer where)
- (ledger-navigate-to-line (cdr where))
- (forward-char)
- (setq status (ledger-toggle-current (if ledger-reconcile-toggle-to-pending
- 'pending
- 'cleared)))
- (when ledger-reconcile-insert-effective-date
- ;; Ask for effective date & insert it
- (ledger-insert-effective-date)))
- ;; remove the existing face and add the new face
- (remove-text-properties (line-beginning-position)
- (line-end-position)
- (list 'face))
- (cond ((eq status 'pending)
- (add-text-properties (line-beginning-position)
- (line-end-position)
- (list 'face 'ledger-font-reconciler-pending-face )))
- ((eq status 'cleared)
- (add-text-properties (line-beginning-position)
- (line-end-position)
- (list 'face 'ledger-font-reconciler-cleared-face )))
- (t
- (add-text-properties (line-beginning-position)
- (line-end-position)
- (list 'face 'ledger-font-reconciler-uncleared-face )))))
- (forward-line)
- (beginning-of-line)
- (ledger-display-balance)))
- (defun ledger-reconcile-refresh ()
- "Force the reconciliation window to refresh.
- Return the number of uncleared xacts found."
- (interactive)
- (let ((inhibit-read-only t))
- (erase-buffer)
- (prog1
- (ledger-do-reconcile ledger-reconcile-sort-key)
- (set-buffer-modified-p t))))
- (defun ledger-reconcile-refresh-after-save ()
- "Refresh the recon-window after the ledger buffer is saved."
- (let ((curbufwin (get-buffer-window (current-buffer)))
- (curpoint (point))
- (recon-buf (get-buffer ledger-recon-buffer-name)))
- (when (buffer-live-p recon-buf)
- (with-current-buffer recon-buf
- (ledger-reconcile-refresh)
- (set-buffer-modified-p nil))
- (when curbufwin
- (select-window curbufwin)
- (goto-char curpoint)))))
- (defun ledger-reconcile-add ()
- "Use ledger xact to add a new transaction."
- (interactive)
- (with-current-buffer ledger-buf
- (call-interactively #'ledger-add-transaction))
- (ledger-reconcile-refresh))
- (defun ledger-reconcile-delete ()
- "Delete the transactions pointed to in the recon window."
- (interactive)
- (let ((where (get-text-property (point) 'where)))
- (when (ledger-reconcile-get-buffer where)
- (with-current-buffer (ledger-reconcile-get-buffer where)
- (ledger-navigate-to-line (cdr where))
- (ledger-delete-current-transaction (point)))
- (let ((inhibit-read-only t))
- (goto-char (line-beginning-position))
- (delete-region (point) (1+ (line-end-position)))
- (set-buffer-modified-p t))
- (ledger-reconcile-refresh))))
- (defun ledger-reconcile-visit (&optional come-back)
- "Recenter ledger buffer on transaction and COME-BACK if non-nil."
- (interactive)
- (beginning-of-line)
- (let* ((where (get-text-property (1+ (point)) 'where))
- (target-buffer (if where
- (ledger-reconcile-get-buffer where)
- nil))
- (cur-win (get-buffer-window (get-buffer ledger-recon-buffer-name))))
- (when target-buffer
- (switch-to-buffer-other-window target-buffer)
- (ledger-navigate-to-line (cdr where))
- (forward-char)
- (recenter)
- (ledger-highlight-xact-under-point)
- (forward-char -1)
- (when (and come-back cur-win)
- (select-window cur-win)
- (get-buffer ledger-recon-buffer-name)))))
- (defun ledger-reconcile-save ()
- "Save the ledger buffer."
- (interactive)
- (let ((cur-buf (current-buffer))
- (cur-point (point)))
- (dolist (buf (cons ledger-buf ledger-bufs))
- (with-current-buffer buf
- (basic-save-buffer)))
- (switch-to-buffer-other-window cur-buf)
- (goto-char cur-point)))
- (defun ledger-reconcile-finish ()
- "Mark all pending posting or transactions as cleared.
- Depends on ledger-reconcile-clear-whole-transactions, save the buffers
- and exit reconcile mode if `ledger-reconcile-finish-force-quit'"
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (while (not (eobp))
- (let ((where (get-text-property (point) 'where))
- (face (get-text-property (point) 'face)))
- (if (eq face 'ledger-font-reconciler-pending-face)
- (with-current-buffer (ledger-reconcile-get-buffer where)
- (ledger-navigate-to-line (cdr where))
- (ledger-toggle-current 'cleared))))
- (forward-line 1)))
- (ledger-reconcile-save)
- (when ledger-reconcile-finish-force-quit
- (ledger-reconcile-quit)))
- (defun ledger-reconcile-quit ()
- "Quit the reconcile window without saving ledger buffer."
- (interactive)
- (let ((recon-buf (get-buffer ledger-recon-buffer-name))
- buf)
- (if recon-buf
- (with-current-buffer recon-buf
- (ledger-reconcile-quit-cleanup)
- (setq buf ledger-buf)
- ;; Make sure you delete the window before you delete the buffer,
- ;; otherwise, madness ensues
- (delete-window (get-buffer-window recon-buf))
- (kill-buffer recon-buf)
- (set-window-buffer (selected-window) buf)))))
- (defun ledger-reconcile-quit-cleanup ()
- "Cleanup all hooks established by reconcile mode."
- (interactive)
- (let ((buf ledger-buf))
- (if (buffer-live-p buf)
- (with-current-buffer buf
- (remove-hook 'after-save-hook 'ledger-reconcile-refresh-after-save t)
- (when ledger-narrow-on-reconcile
- (ledger-occur-mode -1)
- (ledger-highlight-xact-under-point))))))
- (defun ledger-marker-where-xact-is (emacs-xact posting)
- "Find the position of the EMACS-XACT in the `ledger-buf'.
- POSTING is used in `ledger-clear-whole-transactions' is nil."
- (let ((buf (if (ledger-is-stdin (nth 0 emacs-xact))
- ledger-buf
- (find-file-noselect (nth 0 emacs-xact)))))
- (cons
- buf
- (if ledger-clear-whole-transactions
- (nth 1 emacs-xact) ;; return line-no of xact
- (nth 0 posting))))) ;; return line-no of posting
- (defun ledger-reconcile-compile-format-string (fstr)
- "Return a function that implements the format string in FSTR."
- (let (fields
- (start 0))
- (while (string-match "(\\(.*?\\))" fstr start)
- (setq fields (cons (intern (match-string 1 fstr)) fields))
- (setq start (match-end 0)))
- (setq fields (list* 'format (replace-regexp-in-string "(.*?)" "" fstr) (nreverse fields)))
- `(lambda (date code status payee account amount)
- ,fields)))
- (defun ledger-reconcile-format-posting (beg where fmt date code status payee account amount)
- "Format posting for the reconcile buffer."
- (insert (funcall fmt date code status payee account amount))
- ; Set face depending on cleared status
- (if status
- (if (eq status 'pending)
- (set-text-properties beg (1- (point))
- (list 'face 'ledger-font-reconciler-pending-face
- 'where where))
- (set-text-properties beg (1- (point))
- (list 'face 'ledger-font-reconciler-cleared-face
- 'where where)))
- (set-text-properties beg (1- (point))
- (list 'face 'ledger-font-reconciler-uncleared-face
- 'where where))))
- (defun ledger-reconcile-format-xact (xact fmt)
- "Format XACT using FMT."
- (let ((date-format (or (cdr (assoc "date-format" ledger-environment-alist))
- ledger-default-date-format)))
- (dolist (posting (nthcdr 5 xact))
- (let ((beg (point))
- (where (ledger-marker-where-xact-is xact posting)))
- (ledger-reconcile-format-posting beg
- where
- fmt
- (format-time-string date-format (nth 2 xact)) ; date
- (if (nth 3 xact) (nth 3 xact) "") ; code
- (nth 3 posting) ; status
- (ledger-reconcile-truncate-right
- (nth 4 xact) ; payee
- ledger-reconcile-buffer-payee-max-chars)
- (ledger-reconcile-truncate-left
- (nth 1 posting) ; account
- ledger-reconcile-buffer-account-max-chars)
- (nth 2 posting)))))) ; amount
- (defun ledger-do-reconcile (&optional sort)
- "SORT the uncleared transactions in the account and display them in the *Reconcile* buffer.
- Return a count of the uncleared transactions."
- (let* ((buf ledger-buf)
- (account ledger-acct)
- (ledger-success nil)
- (sort-by (if sort
- sort
- "(date)"))
- (xacts
- (with-temp-buffer
- (when (ledger-exec-ledger buf (current-buffer)
- "--uncleared" "--real" "emacs" "--sort" sort-by account)
- (setq ledger-success t)
- (goto-char (point-min))
- (unless (eobp)
- (if (looking-at "(")
- (read (current-buffer))))))) ;current-buffer is the *temp* created above
- (fmt (ledger-reconcile-compile-format-string ledger-reconcile-buffer-line-format)))
- (if (and ledger-success (> (length xacts) 0))
- (progn
- (insert (format ledger-reconcile-buffer-header account))
- (dolist (xact xacts)
- (ledger-reconcile-format-xact xact fmt))
- (goto-char (point-max))
- (delete-char -1)) ;gets rid of the extra line feed at the bottom of the list
- (if ledger-success
- (insert (concat "There are no uncleared entries for " account))
- (insert "Ledger has reported a problem. Check *Ledger Error* buffer.")))
- (goto-char (point-min))
- (set-buffer-modified-p nil)
- (setq buffer-read-only t)
- (ledger-reconcile-ensure-xacts-visible)
- (length xacts)))
- (defun ledger-reconcile-ensure-xacts-visible ()
- "Ensure the last of the visible transactions in the ledger buffer is at the bottom of the main window.
- The key to this is to ensure the window is selected when the buffer point is
- moved and recentered. If they aren't strange things happen."
- (let ((recon-window (get-buffer-window (get-buffer ledger-recon-buffer-name))))
- (when recon-window
- (fit-window-to-buffer recon-window)
- (with-current-buffer ledger-buf
- (add-hook 'kill-buffer-hook 'ledger-reconcile-quit nil t)
- (if (get-buffer-window ledger-buf)
- (select-window (get-buffer-window ledger-buf)))
- (goto-char (point-max))
- (recenter -1))
- (select-window recon-window)
- (ledger-reconcile-visit t))
- (add-hook 'post-command-hook 'ledger-reconcile-track-xact nil t)))
- (defun ledger-reconcile-track-xact ()
- "Force the ledger buffer to recenter on the transaction at point in the reconcile buffer."
- (if (and ledger-buffer-tracks-reconcile-buffer
- (member this-command (list 'next-line
- 'previous-line
- 'mouse-set-point
- 'ledger-reconcile-toggle
- 'end-of-buffer
- 'beginning-of-buffer)))
- (save-excursion
- (ledger-reconcile-visit t))))
- (defun ledger-reconcile-open-windows (buf rbuf)
- "Ensure that the ledger buffer BUF is split by RBUF."
- (if ledger-reconcile-force-window-bottom
- ;;create the *Reconcile* window directly below the ledger buffer.
- (set-window-buffer (split-window (get-buffer-window buf) nil nil) rbuf)
- (pop-to-buffer rbuf)))
- (defun ledger-reconcile-check-valid-account (account)
- "Check to see if ACCOUNT exists in the ledger file"
- (if (> (length account) 0)
- (save-excursion
- (goto-char (point-min))
- (search-forward account nil t))))
- (defun ledger-reconcile ()
- "Start reconciling, prompt for account."
- (interactive)
- (let ((account (ledger-read-account-with-prompt "Account to reconcile"))
- (buf (current-buffer))
- (rbuf (get-buffer ledger-recon-buffer-name)))
- (when (ledger-reconcile-check-valid-account account)
- (add-hook 'after-save-hook 'ledger-reconcile-refresh-after-save nil t)
- (if rbuf ;; *Reconcile* already exists
- (with-current-buffer rbuf
- (set 'ledger-acct account) ;; already buffer local
- (when (not (eq buf rbuf))
- ;; called from some other ledger-mode buffer
- (ledger-reconcile-quit-cleanup)
- (setq ledger-buf buf)) ;; should already be buffer-local
- (unless (get-buffer-window rbuf)
- (ledger-reconcile-open-windows buf rbuf)))
- ;; no recon-buffer, starting from scratch.
- (with-current-buffer (setq rbuf
- (get-buffer-create ledger-recon-buffer-name))
- (ledger-reconcile-open-windows buf rbuf)
- (ledger-reconcile-mode)
- (make-local-variable 'ledger-target)
- (set (make-local-variable 'ledger-buf) buf)
- (set (make-local-variable 'ledger-acct) account)))
- ;; Narrow the ledger buffer
- (with-current-buffer rbuf
- (save-excursion
- (if ledger-narrow-on-reconcile
- (ledger-occur account)))
- (if (> (ledger-reconcile-refresh) 0)
- (ledger-reconcile-change-target))
- (ledger-display-balance)))))
- (defvar ledger-reconcile-mode-abbrev-table)
- (defun ledger-reconcile-change-target ()
- "Change the target amount for the reconciliation process."
- (interactive)
- (setq ledger-target (ledger-read-commodity-string ledger-reconcile-target-prompt-string)))
- (defmacro ledger-reconcile-change-sort-key-and-refresh (sort-by)
- "Set the sort-key to SORT-BY."
- `(lambda ()
- (interactive)
- (setq ledger-reconcile-sort-key ,sort-by)
- (ledger-reconcile-refresh)))
- (defvar ledger-reconcile-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [(control ?m)] 'ledger-reconcile-visit)
- (define-key map [return] 'ledger-reconcile-visit)
- (define-key map [(control ?x) (control ?s)] 'ledger-reconcile-save)
- (define-key map [(control ?l)] 'ledger-reconcile-refresh)
- (define-key map [(control ?c) (control ?c)] 'ledger-reconcile-finish)
- (define-key map [? ] 'ledger-reconcile-toggle)
- (define-key map [?a] 'ledger-reconcile-add)
- (define-key map [?d] 'ledger-reconcile-delete)
- (define-key map [?g] 'ledger-reconcile);
- (define-key map [?n] 'next-line)
- (define-key map [?p] 'previous-line)
- (define-key map [?t] 'ledger-reconcile-change-target)
- (define-key map [?s] 'ledger-reconcile-save)
- (define-key map [?q] 'ledger-reconcile-quit)
- (define-key map [?b] 'ledger-display-balance)
- (define-key map [(control ?c) (control ?o)] (ledger-reconcile-change-sort-key-and-refresh "(0)"))
- (define-key map [(control ?c) (control ?a)] (ledger-reconcile-change-sort-key-and-refresh "(amount)"))
- (define-key map [(control ?c) (control ?d)] (ledger-reconcile-change-sort-key-and-refresh "(date)"))
- (define-key map [(control ?c) (control ?p)] (ledger-reconcile-change-sort-key-and-refresh "(payee)"))
- map)
- "Keymap for `ledger-reconcile-mode'.")
- (easy-menu-define ledger-reconcile-mode-menu ledger-reconcile-mode-map
- "Ledger reconcile menu"
- `("Reconcile"
- ["Save" ledger-reconcile-save]
- ["Refresh" ledger-reconcile-refresh]
- ["Finish" ledger-reconcile-finish]
- "---"
- ["Reconcile New Account" ledger-reconcile]
- "---"
- ["Change Target Balance" ledger-reconcile-change-target]
- ["Show Cleared Balance" ledger-display-balance]
- "---"
- ["Sort by payee" ,(ledger-reconcile-change-sort-key-and-refresh "(payee)")]
- ["Sort by date" ,(ledger-reconcile-change-sort-key-and-refresh "(date)")]
- ["Sort by amount" ,(ledger-reconcile-change-sort-key-and-refresh "(amount)")]
- ["Sort by file order" ,(ledger-reconcile-change-sort-key-and-refresh "(0)")]
- "---"
- ["Toggle Entry" ledger-reconcile-toggle]
- ["Add Entry" ledger-reconcile-add]
- ["Delete Entry" ledger-reconcile-delete]
- "---"
- ["Next Entry" next-line]
- ["Visit Source" ledger-reconcile-visit]
- ["Previous Entry" previous-line]
- "---"
- ["Quit" ledger-reconcile-quit]
- ))
- (define-derived-mode ledger-reconcile-mode text-mode "Reconcile"
- "A mode for reconciling ledger entries.")
- (provide 'ledger-reconcile)
- ;;; ledger-reconcile.el ends here
|