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

@ -41,9 +41,17 @@
(defun ledger-remove-overlays ()
"Remove all overlays from the ledger buffer."
(interactive)
"remove overlays formthe buffer, used if the buffer is reverted"
(remove-overlays))
(interactive)
(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)
@ -70,7 +78,7 @@
(add-hook 'post-command-hook 'ledger-highlight-xact-under-point nil t)
(add-hook 'before-revert-hook 'ledger-remove-overlays nil t)
(make-variable-buffer-local 'highlight-overlay)
(ledger-init-load-init-file)
(let ((map (current-local-map)))
@ -86,8 +94,8 @@
(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 ?y)] 'ledger-set-year)
(define-key map [tab] 'pcomplete)
(define-key map [(control ?i)] 'pcomplete)
(define-key map [tab] 'ledger-magic-tab)
(define-key map [(control ?i)] 'ledger-magic-tab)
(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 ?o) (control ?r)] 'ledger-report)

View file

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