*** empty log message ***

This commit is contained in:
John Wiegley 2004-04-04 11:09:59 +00:00
parent 47eebe8d73
commit c68b502156
3 changed files with 107 additions and 69 deletions

View file

@ -63,7 +63,7 @@ void transaction::print(std::ostream& out, bool display_quantity,
void entry::print(std::ostream& out, bool shortcut) const void entry::print(std::ostream& out, bool shortcut) const
{ {
char buf[32]; char buf[32];
std::strftime(buf, 31, "%Y.%m.%d ", std::localtime(&date)); std::strftime(buf, 31, "%Y/%m/%d ", std::localtime(&date));
out << buf; out << buf;
if (cleared) if (cleared)

144
ledger.el
View file

@ -37,16 +37,66 @@
(defvar ledger-version "1.1" (defvar ledger-version "1.1"
"The version of ledger.el currently loaded") "The version of ledger.el currently loaded")
(defun ledger-iterate-entries (callback)
(goto-char (point-min))
(let* ((now (current-time))
(current-year (nth 5 (decode-time now))))
(while (not (eobp))
(when (looking-at
(concat "\\(Y\\s-+\\([0-9]+\\)\\|"
"\\([0-9]\\{4\\}+\\)?[./]?"
"\\([0-9]+\\)[./]\\([0-9]+\\)\\s-+"
"\\(\\*\\s-+\\)?\\(.+\\)\\)"))
(let ((found (match-string 2)))
(if found
(setq current-year (string-to-number found))
(let ((start (match-beginning 0))
(year (match-string 3))
(month (string-to-number (match-string 4)))
(day (string-to-number (match-string 5)))
(mark (match-string 6))
(desc (match-string 7)))
(if (and year (> (length year) 0))
(setq year (string-to-number year)))
(funcall callback start
(encode-time 0 0 0 day month
(or year current-year))
mark desc)))))
(forward-line))))
(defun ledger-find-slot (moment)
(catch 'found
(ledger-iterate-entries
(function
(lambda (start date mark desc)
(if (time-less-p moment date)
(throw 'found t)))))))
(defun ledger-add-entry (entry) (defun ledger-add-entry (entry)
(interactive (interactive
(list (read-string "Entry: " (list (read-string "Entry: " (format-time-string "%m/%d "))))
(format-time-string "%m.%d " (current-time))))) (let ((args (mapcar 'shell-quote-argument (split-string entry)))
(let ((args (mapcar 'shell-quote-argument (split-string entry)))) date entry)
(shell-command (with-temp-buffer
(concat "ledger entry " (shell-command
(mapconcat 'identity args " ")) t) (concat "ledger entry "
(delete-char 5) (mapconcat 'identity args " ")) t)
(exchange-point-and-mark))) (setq date (buffer-substring (point) (+ (point) 10)))
(setq entry (buffer-substring (+ (point) 5) (point-max))))
(if (string-match "\\([0-9]+\\)/\\([0-9]+\\)/\\([0-9]+\\)" date)
(setq date (encode-time 0 0 0 (string-to-int (match-string 3 date))
(string-to-int (match-string 2 date))
(string-to-int (match-string 1 date)))))
(ledger-find-slot date)
(insert entry)))
(defun ledger-expand-entry ()
(interactive)
(ledger-add-entry (prog1
(buffer-substring (line-beginning-position)
(line-end-position))
(delete-region (line-beginning-position)
(1+ (line-end-position))))))
(defun ledger-toggle-current () (defun ledger-toggle-current ()
(interactive) (interactive)
@ -64,57 +114,37 @@
(define-derived-mode ledger-mode text-mode "Ledger" (define-derived-mode ledger-mode text-mode "Ledger"
"A mode for editing ledger data files." "A mode for editing ledger data files."
(setq comment-start ";" comment-end nil) (setq comment-start ";" comment-end nil
indent-tabs-mode nil)
(let ((map (current-local-map))) (let ((map (current-local-map)))
(define-key map [(control ?c) (control ?n)] 'ledger-add-entry) (define-key map [(control ?c) (control ?a)] 'ledger-add-entry)
(define-key map [(control ?c) (control ?c)] (define-key map [(control ?c) (control ?c)] 'ledger-toggle-current)))
'ledger-toggle-current)))
(defun ledger-parse-entries (account) (defun ledger-parse-entries (account &optional all-p)
(let* ((now (current-time)) ;; `then' is 45 days ago
(current-year (nth 5 (decode-time now))) (let ((then (time-subtract (current-time)
(then now) (seconds-to-time (* 45 24 60 60))))
entries) total entries)
;; `then' is 45 days ago (ledger-iterate-entries
(setq then (time-subtract then (seconds-to-time (* 45 24 60 60)))) (function
(while (not (eobp)) (lambda (start date mark desc)
(when (looking-at (when (or all-p (not mark) (time-less-p then date))
(concat "\\(Y\\s-+\\([0-9]+\\)\\|" (forward-line)
"\\([0-9]\\{4\\}+\\)?[./]?" (setq total 0.0)
"\\([0-9]+\\)[./]\\([0-9]+\\)\\s-+" (while (looking-at
"\\(\\*\\s-+\\)?\\(.+\\)\\)")) (concat "\\s-+\\([A-Za-z_].+?\\)\\(\\s-*$\\| \\s-*"
(let ((found (match-string 2)) "\\([^0-9]+\\)\\s-*\\([0-9.]+\\)\\)"))
total when) (let ((acct (match-string 1))
(if found (amt (match-string 4)))
(setq current-year (string-to-number found)) (if amt
(let ((start (match-beginning 0)) (setq amt (string-to-number amt)
(year (match-string 3)) total (+ total amt)))
(month (string-to-number (match-string 4))) (if (string= account acct)
(day (string-to-number (match-string 5))) (setq entries
(mark (match-string 6)) (cons (list (copy-marker start)
(desc (match-string 7))) mark date desc (or amt total))
(if (and year (> (length year) 0)) entries))))
(setq year (string-to-number year))) (forward-line))))))
(setq when (encode-time 0 0 0 day month
(or year current-year)))
(when (or (not mark) (time-less-p then when))
(forward-line)
(setq total 0.0)
(while (looking-at
(concat "\\s-+\\([A-Za-z_].+?\\)\\(\\s-*$\\| \\s-*"
"\\([^0-9]+\\)\\s-*\\([0-9.]+\\)\\)"))
(let ((acct (match-string 1))
(amt (match-string 4)))
(if amt
(setq amt (string-to-number amt)
total (+ total amt)))
(if (string= account acct)
(setq entries
(cons (list (copy-marker start)
mark when desc (or amt total))
entries))))
(forward-line)))))))
(forward-line))
(nreverse entries))) (nreverse entries)))
(define-derived-mode ledger-reconcile-mode text-mode "Reconcile" (define-derived-mode ledger-reconcile-mode text-mode "Reconcile"

View file

@ -369,7 +369,7 @@ void add_new_entry(int index, int argc, char **argv)
assert(index < argc); assert(index < argc);
if (! parse_date(argv[index++], &added.date)) { if (! parse_date(argv[index++], &added.date)) {
std::cerr << "Error: Bad add date: " << argv[index - 1] std::cerr << "Error: Bad entry date: " << argv[index - 1]
<< std::endl; << std::endl;
std::exit(1); std::exit(1);
} }
@ -377,7 +377,7 @@ void add_new_entry(int index, int argc, char **argv)
added.cleared = show_cleared; added.cleared = show_cleared;
if (index == argc) { if (index == argc) {
std::cerr << "Error: Too few arguments to 'add'." << std::endl; std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
std::exit(1); std::exit(1);
} }
@ -396,7 +396,7 @@ void add_new_entry(int index, int argc, char **argv)
added.desc = matching ? matching->desc : regexps.front().pattern; added.desc = matching ? matching->desc : regexps.front().pattern;
if (index == argc) { if (index == argc) {
std::cerr << "Error: Too few arguments to 'add'." << std::endl; std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
std::exit(1); std::exit(1);
} }
@ -437,11 +437,13 @@ void add_new_entry(int index, int argc, char **argv)
mask acct_regex(argv[index++]); mask acct_regex(argv[index++]);
account * acct = NULL; account * acct = NULL;
commodity * cmdty = NULL;
for (std::list<transaction *>::iterator x = matching->xacts.begin(); for (std::list<transaction *>::iterator x = matching->xacts.begin();
x != matching->xacts.end(); x != matching->xacts.end();
x++) { x++) {
if (acct_regex.match((*x)->acct->as_str())) { if (acct_regex.match((*x)->acct->as_str())) {
acct = (*x)->acct; acct = (*x)->acct;
cmdty = (*x)->cost->commdty();
break; break;
} }
} }
@ -458,16 +460,18 @@ void add_new_entry(int index, int argc, char **argv)
} }
if (index == argc) { if (index == argc) {
std::cerr << "Error: Too few arguments to 'add'." << std::endl; std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
std::exit(1); std::exit(1);
} }
xact->cost = create_amount(argv[index++]); xact->cost = create_amount(argv[index++]);
if (! xact->cost->commdty())
xact->cost->set_commdty(cmdty);
added.xacts.push_back(xact); added.xacts.push_back(xact);
} }
if ((index + 1) < argc && std::string(argv[index]) == "-from") if ((index + 1) < argc && std::string(argv[index]) == "-from") {
if (account * acct = main_ledger->re_find_account(argv[++index])) { if (account * acct = main_ledger->re_find_account(argv[++index])) {
transaction * xact = new transaction(); transaction * xact = new transaction();
xact->acct = acct; xact->acct = acct;
@ -475,15 +479,21 @@ void add_new_entry(int index, int argc, char **argv)
added.xacts.push_back(xact); added.xacts.push_back(xact);
} }
} else {
transaction * xact = new transaction();
xact->acct = matching->xacts.back()->acct;
xact->cost = NULL;
added.xacts.push_back(xact);
}
} }
if (added.finalize()) if (added.finalize())
added.print(std::cout); added.print(std::cout);
} }
// Print out the entire ledger that was read in, sorted by date. // Print out the entire ledger that was read in. This can be used to
// This can be used to "wash" ugly ledger files. It's written here, // "wash" ugly ledger files. It's written here, instead of ledger.cc,
// instead of ledger.cc, in order to access the static globals above. // in order to access the static globals above.
void book::print(std::ostream& out, regexps_map& regexps, void book::print(std::ostream& out, regexps_map& regexps,
bool shortcut) const bool shortcut) const
@ -491,9 +501,7 @@ void book::print(std::ostream& out, regexps_map& regexps,
for (entries_list_const_iterator i = entries.begin(); for (entries_list_const_iterator i = entries.begin();
i != entries.end(); i != entries.end();
i++) { i++) {
if ((! show_cleared && (*i)->cleared) || if (! matches_date_range(*i) || ! (*i)->matches(regexps))
! matches_date_range(*i) ||
! (*i)->matches(regexps))
continue; continue;
(*i)->print(out, shortcut); (*i)->print(out, shortcut);