Rewrote ledger-post-align-postings to address bugs 923 924 925 926 927 and 928.

This commit is contained in:
Craig Earls 2013-03-23 19:54:40 -07:00
parent 89d480f510
commit 99973d0c0c
2 changed files with 72 additions and 59 deletions

View file

@ -42,9 +42,17 @@
(defun ledger-remove-overlays () (defun ledger-remove-overlays ()
"Remove all overlays from the ledger buffer." "Remove all overlays from the ledger buffer."
(interactive) (interactive)
"remove overlays formthe buffer, used if the buffer is reverted"
(remove-overlays)) (remove-overlays))
(defun ledger-magic-tab ()
"Decide what to with with <TAB> .
Can be pcomplete, or align-posting"
(interactive)
(if (and (> (point) 1)
(looking-back "[:A-Za-z0-9]" 1))
(pcomplete)
(ledger-post-align-postings)))
(defvar ledger-mode-abbrev-table) (defvar ledger-mode-abbrev-table)
;;;###autoload ;;;###autoload
@ -86,8 +94,8 @@
(define-key map [(control ?c) (control ?s)] 'ledger-sort-region) (define-key map [(control ?c) (control ?s)] 'ledger-sort-region)
(define-key map [(control ?c) (control ?t)] 'ledger-test-run) (define-key map [(control ?c) (control ?t)] 'ledger-test-run)
(define-key map [(control ?c) (control ?y)] 'ledger-set-year) (define-key map [(control ?c) (control ?y)] 'ledger-set-year)
(define-key map [tab] 'pcomplete) (define-key map [tab] 'ledger-magic-tab)
(define-key map [(control ?i)] 'pcomplete) (define-key map [(control ?i)] 'ledger-magic-tab)
(define-key map [(control ?c) tab] 'ledger-fully-complete-entry) (define-key map [(control ?c) tab] 'ledger-fully-complete-entry)
(define-key map [(control ?c) (control ?i)] 'ledger-fully-complete-entry) (define-key map [(control ?c) (control ?i)] 'ledger-fully-complete-entry)
(define-key map [(control ?c) (control ?o) (control ?r)] 'ledger-report) (define-key map [(control ?c) (control ?o) (control ?r)] 'ledger-report)

View file

@ -116,65 +116,70 @@ PROMPT is a string to prompt with. CHOICES is a list of
(goto-char pos))) (goto-char pos)))
(defun ledger-next-amount (&optional end) (defun ledger-next-amount (&optional end)
"Move point to the next amount, as long as it is not past END." "Move point to the next amount, as long as it is not past END.
Return the width of the amount field as an integer."
(beginning-of-line)
(when (re-search-forward "\\( \\|\t\\| \t\\)[ \t]*-?\\([A-Z$€£]+ *\\)?\\(-?[0-9,]+?\\)\\(.[0-9]+\\)?\\( *[A-Z$€£]+\\)?\\([ \t]*@@?[^\n;]+?\\)?\\([ \t]+;.+?\\|[ \t]*\\)?$" (marker-position end) t) (when (re-search-forward "\\( \\|\t\\| \t\\)[ \t]*-?\\([A-Z$€£]+ *\\)?\\(-?[0-9,]+?\\)\\(.[0-9]+\\)?\\( *[A-Z$€£]+\\)?\\([ \t]*@@?[^\n;]+?\\)?\\([ \t]+;.+?\\|[ \t]*\\)?$" (marker-position end) t)
(goto-char (match-beginning 0)) (goto-char (match-beginning 0))
(skip-syntax-forward " ") (skip-syntax-forward " ")
(- (or (match-end 4) (- (or (match-end 4)
(match-end 3)) (point)))) (match-end 3)) (point))))
(defun ledger-post-align-posting (&optional column) (defun ledger-next-account (&optional end)
"Align amounts and accounts in the current posting. "Move point to the beginning of the next account, or status marker (!*), as long as it is not past END.
This is done so that the last digit falls in COLUMN, which Return the column of the beginning of the account"
defaults to 52. ledger-post-account-column positions (beginning-of-line)
the account" (if (> (marker-position end) (point))
(interactive "p") (when (re-search-forward "\\(^[ ]+\\)\\([*!;a-zA-Z0-9]+?\\)" (marker-position end) t)
(if (or (null column) (= column 1)) (goto-char (match-beginning 2))
(setq column ledger-post-amount-alignment-column)) (current-column))))
(save-excursion
;; Position the account (defun ledger-post-align-postings ()
(if (not (or (looking-at "[ \t]*[1-9]") "Align all accounts and amounts within region, if there is no
(and (looking-at "[ \t]+\n") region alight the posting on the current line."
(looking-back "[ \n]" (- (point) 2))))) (interactive)
(save-excursion (save-excursion
;; If there is no region set
(when (or (not (mark))
(= (point) (mark)))
(beginning-of-line) (beginning-of-line)
(set-mark (point)) (set-mark (point))
(delete-horizontal-space) (goto-char (1+ (line-end-position))))
(insert (make-string ledger-post-account-alignment-column ? )))
(set-mark (point)))
(set-mark (point))
(goto-char (1+ (line-end-position)))
(let* ((mark-first (< (mark) (point))) (let* ((mark-first (< (mark) (point)))
(begin (if mark-first (mark) (point))) (begin (if mark-first (mark) (point)))
(end (if mark-first (point-marker) (mark-marker))) (end (if mark-first (point-marker) (mark-marker)))
offset) acc-col amt-offset)
;; Position the amount (goto-char end)
(end-of-line)
(setq end (point-marker))
(goto-char begin) (goto-char begin)
(while (setq offset (ledger-next-amount end)) (beginning-of-line)
(let ((col (current-column)) (setq begin (point-marker))
(target-col (- column offset)) (while (setq acc-col (ledger-next-account end))
adjust) ;; Adjust account position if necessary
(setq adjust (- target-col col)) (let ((acc-adjust (- ledger-post-account-alignment-column acc-col)))
(if (< col target-col) (if (/= acc-adjust 0)
(insert (make-string (- target-col col) ? )) (if (> acc-adjust 0)
(move-to-column target-col) (insert (make-string acc-adjust ? )) ;; Account too far left
(if (looking-back " ") (if (looking-back " " (- (point) 3))
(delete-char (- col target-col)) (delete-char acc-adjust)
(skip-chars-forward "^ \t") (skip-chars-forward "^ \t")
(delete-horizontal-space) (delete-horizontal-space)
(insert " "))) (insert " ")))))
(forward-line)))))) (when (setq amt-offset (ledger-next-amount end))
(let* ((amt-adjust (- ledger-post-amount-alignment-column
amt-offset
(defun ledger-post-align-region (beg end) (current-column))))
(interactive "r") (if (/= amt-adjust 0)
(save-excursion (if (> amt-adjust 0)
(goto-char beg) (insert (make-string amt-adjust ? ))
(backward-paragraph) ;; make sure we are at the beginning of an xact (if (looking-back " ")
(while (< (point) end) (delete-char amt-adjust)
(ledger-post-align-posting) (skip-chars-forward "^ \t")
(forward-line)))) (delete-horizontal-space)
(insert " "))))))
(forward-line)))))
(defun ledger-post-maybe-align (beg end len) (defun ledger-post-maybe-align (beg end len)
"Align amounts only if point is in a posting. "Align amounts only if point is in a posting.
@ -185,7 +190,7 @@ BEG, END, and LEN control how far it can align."
(when (<= end (line-end-position)) (when (<= end (line-end-position))
(goto-char (line-beginning-position)) (goto-char (line-beginning-position))
(if (looking-at ledger-post-line-regexp) (if (looking-at ledger-post-line-regexp)
(ledger-post-align-posting)))))) (ledger-post-align-postings))))))
(defun ledger-post-edit-amount () (defun ledger-post-edit-amount ()
"Call 'calc-mode' and push the amount in the posting to the top of stack." "Call 'calc-mode' and push the amount in the posting to the top of stack."