reconcile mode windowing improvements

* reconcile mode now places its window at the bottom of the ledger window it was called form and minimizes its height to the size of the recon buffer.
* It all specifically informs the user if there are no uncleared items.
* When reconcile mode is entered it sets the ledger-occur mode and scrolls the bottom of the visible buffer to the bottom of the ledger window ensuring transactions are visible.
This commit is contained in:
Craig Earls 2013-02-07 09:12:44 -07:00
parent 3d34a61ed5
commit e3431c4bff

View file

@ -23,12 +23,14 @@
(defvar ledger-buf nil) (defvar ledger-buf nil)
(defvar ledger-acct nil) (defvar ledger-acct nil)
(defcustom ledger-recon-buffer-name "*Reconcile*"
"Name to use for reconciliation window"
:group 'ledger)
(defcustom ledger-fold-on-reconcile t (defcustom ledger-fold-on-reconcile t
"if t, limit transactions shown in main buffer to those "if t, limit transactions shown in main buffer to those
matching the reconcile regex" matching the reconcile regex"
:group 'ledger) :group 'ledger)
(make-variable-buffer-local 'ledger-fold-on-reconcilex)
(defun ledger-display-balance () (defun ledger-display-balance ()
"Calculate the cleared balance of the account being reconciled" "Calculate the cleared balance of the account being reconciled"
@ -95,7 +97,7 @@
(forward-line line))) (forward-line line)))
(defun ledger-reconcile-refresh-after-save () (defun ledger-reconcile-refresh-after-save ()
(let ((buf (get-buffer "*Reconcile*"))) (let ((buf (get-buffer ledger-recon-buffer-name)))
(if buf (if buf
(with-current-buffer buf (with-current-buffer buf
(ledger-reconcile-refresh) (ledger-reconcile-refresh)
@ -136,6 +138,9 @@
(defun ledger-reconcile-quit () (defun ledger-reconcile-quit ()
(interactive) (interactive)
(let ((buf ledger-buf)) (let ((buf ledger-buf))
;Make sure you delete the window before you delete the buffer,
;otherwise, madness ensues
(delete-window (get-buffer-window (current-buffer)))
(kill-buffer (current-buffer)) (kill-buffer (current-buffer))
(if ledger-fold-on-reconcile (if ledger-fold-on-reconcile
(ledger-occur-quit-buffer buf)))) (ledger-occur-quit-buffer buf))))
@ -155,34 +160,44 @@
(forward-line 1))) (forward-line 1)))
(ledger-reconcile-save)) (ledger-reconcile-save))
(defun ledger-do-reconcile () (defun ledger-marker-where-xact-is (emacs-xact)
"get the uncleared transactions in the account and display them in the *Reconcile* buffer" "find the position of the xact in the ledger-buf buffer using
(let* ((buf ledger-buf) the emacs output from ledger, return a marker to the beginning
(account ledger-acct) of the xact in the buffer"
(items (let ((buf ledger-buf))
(with-temp-buffer (with-current-buffer buf ;use the ledger-buf buffer
(ledger-exec-ledger buf (current-buffer) "--uncleared" "--real"
"emacs" account)
(goto-char (point-min))
(unless (eobp)
(unless (looking-at "(")
(error (buffer-string)))
(read (current-buffer))))))
(dolist (item items)
(let ((index 1))
(dolist (xact (nthcdr 5 item))
(let ((beg (point))
(where
(with-current-buffer buf
(cons (cons
(nth 0 item) (nth 0 item)
(if ledger-clear-whole-entries (if ledger-clear-whole-entries ;determines whether to
;clear on the payee line
;or posting line
(save-excursion (save-excursion
(goto-line (nth 1 item)) (goto-line (nth 1 item))
(point-marker)) (point-marker))
(save-excursion (save-excursion
(goto-line (nth 0 xact)) (goto-line (nth 0 xact))
(point-marker))))))) (point-marker)))))))
(defun ledger-do-reconcile ()
"get the uncleared transactions in the account and display them
in the *Reconcile* buffer"
(let* ((buf ledger-buf)
(account ledger-acct)
(items
(with-temp-buffer
(ledger-exec-ledger buf (current-buffer)
"--uncleared" "--real" "emacs" account)
(goto-char (point-min))
(unless (eobp)
(unless (looking-at "(")
(error (buffer-string)))
(read (current-buffer))))))
(if (> (length items) 0)
(dolist (item items)
(let ((index 1))
(dolist (xact (nthcdr 5 item))
(let ((beg (point))
(where (ledger-marker-where-xact-is item)))
(insert (format "%s %-4s %-30s %-30s %15s\n" (insert (format "%s %-4s %-30s %-30s %15s\n"
(format-time-string "%Y/%m/%d" (nth 2 item)) (format-time-string "%Y/%m/%d" (nth 2 item))
(if (nth 3 item) (if (nth 3 item)
@ -197,22 +212,46 @@
(list 'face 'ledger-font-reconciler-uncleared-face (list 'face 'ledger-font-reconciler-uncleared-face
'where where)))) 'where where))))
(setq index (1+ index))))) (setq index (1+ index)))))
(insert (concat "There are no uncleared entries for " account)))
(goto-char (point-min)) (goto-char (point-min))
(set-buffer-modified-p nil) (set-buffer-modified-p nil)
(toggle-read-only t))) (toggle-read-only t)
; this next piece of code ensures that 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))))
(fit-window-to-buffer recon-window)
(with-current-buffer buf
(select-window (get-buffer-window buf))
(goto-char (point-max))
(recenter -1))
(select-window recon-window))))
(defun ledger-reconcile (account) (defun ledger-reconcile (account)
(interactive "sAccount to reconcile: ") (interactive "sAccount to reconcile: ")
(let ((buf (current-buffer)) (let ((buf (current-buffer))
(rbuf (get-buffer "*Reconcile*"))) (rbuf (get-buffer ledger-recon-buffer-name)))
(if rbuf (if rbuf
(kill-buffer rbuf)) (progn
(quit-window (get-buffer-window rbuf))
(kill-buffer rbuf)))
(add-hook 'after-save-hook 'ledger-reconcile-refresh-after-save) (add-hook 'after-save-hook 'ledger-reconcile-refresh-after-save)
(if ledger-fold-on-reconcile (if ledger-fold-on-reconcile
(ledger-occur-mode account buf)) (ledger-occur-mode account buf))
;create the *Reconcile* window directly below the ledger buffer.
(with-current-buffer (with-current-buffer
(pop-to-buffer (get-buffer-create "*Reconcile*")) (progn
(set-window-buffer
(split-window (get-buffer-window (current-buffer)) nil nil)
(get-buffer-create ledger-recon-buffer-name))
(get-buffer ledger-recon-buffer-name))
(ledger-reconcile-mode) (ledger-reconcile-mode)
(set (make-local-variable 'ledger-buf) buf) (set (make-local-variable 'ledger-buf) buf)
(set (make-local-variable 'ledger-acct) account) (set (make-local-variable 'ledger-acct) account)