summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp/ldg-mode.el38
-rw-r--r--lisp/ldg-reconcile.el136
-rw-r--r--lisp/ldg-report.el15
-rw-r--r--src/output.cc28
-rw-r--r--src/output.h27
-rw-r--r--src/report.cc20
-rw-r--r--src/report.h2
7 files changed, 199 insertions, 67 deletions
diff --git a/lisp/ldg-mode.el b/lisp/ldg-mode.el
index 04c6ee1b..caa57e8e 100644
--- a/lisp/ldg-mode.el
+++ b/lisp/ldg-mode.el
@@ -19,6 +19,7 @@
(defvar ledger-mode-abbrev-table)
+
;;;###autoload
(define-derived-mode ledger-mode text-mode "Ledger"
"A mode for editing ledger data files."
@@ -51,8 +52,41 @@
(define-key map [tab] 'pcomplete)
(define-key map [(control ?i)] 'pcomplete)
(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 ?g)] 'ledger-report-goto)
+ (define-key map [(control ?c) (control ?o) (control ?a)] 'ledger-report-redo)
+ (define-key map [(control ?c) (control ?o) (control ?s)] 'ledger-report-save)
+ (define-key map [(control ?c) (control ?o) (control ?e)] 'ledger-report-edit)
+ (define-key map [(control ?c) (control ?o) (control ?k)] 'ledger-report-kill)
+
+
+ (define-key map [menu-bar] (make-sparse-keymap "ldg-menu"))
+ (define-key map [menu-bar ldg-menu] (cons "Ledger" map))
+
+ (define-key map [menu-bar ldg-menu lrk] '("Kill Report" . ledger-report-kill))
+ (define-key map [menu-bar ldg-menu lre] '("Edit Report" . ledger-report-edit))
+ (define-key map [menu-bar ldg-menu lrs] '("Save Report" . ledger-report-save))
+ (define-key map [menu-bar ldg-menu lrr] '("Re-run Report" . ledger-report-redo))
+ (define-key map [menu-bar ldg-menu lrg] '("Goto Report" . ledger-report-goto))
+ (define-key map [menu-bar ldg-menu lr] '("Run Report" . ledger-report))
+ (define-key map [menu-bar ldg-menu s5] '("--"))
+ (define-key map [menu-bar ldg-menu sm] '("Set Month" . ledger-set-month))
+ (define-key map [menu-bar ldg-menu sy] '("Set Year" . ledger-set-year))
+ (define-key map [menu-bar ldg-menu s1] '("--"))
+ (define-key map [menu-bar ldg-menu so] '("Sort Buffer" . ledger-sort))
+ (define-key map [menu-bar ldg-menu s2] '("--"))
+ (define-key map [menu-bar ldg-menu te] '("Toggle Current Posting" . ledger-toggle-current))
+ (define-key map [menu-bar ldg-menu tt] '("Toggle Current Transaction" . ledger-toggle-current-entry))
+ (define-key map [menu-bar ldg-menu s4] '("--"))
+ (define-key map [menu-bar ldg-menu de] '("Delete Entry" . ledger-delete-current-entry))
+ (define-key map [menu-bar ldg-menu ae] '("Add Entry" . ledger-add-entry))
+ (define-key map [menu-bar ldg-menu s3] '("--"))
+ (define-key map [menu-bar ldg-menu re] '("Reconcile Account" . ledger-reconcile)))
+
+
+
+
(ledger-report-patch-reports (current-buffer)))
(defun ledger-time-less-p (t1 t2)
diff --git a/lisp/ldg-reconcile.el b/lisp/ldg-reconcile.el
index d3dda60f..73409e66 100644
--- a/lisp/ldg-reconcile.el
+++ b/lisp/ldg-reconcile.el
@@ -4,18 +4,24 @@
(defvar ledger-acct nil)
(defun ledger-display-balance ()
+ "Calculate the cleared balance of the account being reconciled"
(let ((buffer ledger-buf)
(account ledger-acct))
(with-temp-buffer
- (let ((exit-code (ledger-run-ledger buffer "-C" "balance" account)))
- (if (/= 0 exit-code)
- (message "Error determining cleared balance")
- (goto-char (1- (point-max)))
- (goto-char (line-beginning-position))
- (delete-horizontal-space)
- (message "Cleared balance = %s"
- (buffer-substring-no-properties (point)
- (line-end-position))))))))
+ (ledger-exec-ledger buffer (current-buffer) "-C" "balance" account)
+ (goto-char (1- (point-max)))
+ (goto-char (line-beginning-position))
+ (delete-horizontal-space)
+ (message "Cleared balance = %s"
+ (buffer-substring-no-properties (point)
+ (line-end-position))))))
+
+(defun is-stdin (file)
+ "True if ledger file is standard input"
+ (or
+ (equal file "")
+ (equal file "<stdin>")
+ (equal file "/dev/stdin")))
(defun ledger-reconcile-toggle ()
(interactive)
@@ -23,18 +29,19 @@
(account ledger-acct)
(inhibit-read-only t)
cleared)
- (when (or (equal (car where) "<stdin>") (equal (car where) "/dev/stdin"))
+ (when (is-stdin (car where))
(with-current-buffer ledger-buf
- (goto-char (cdr where))
- (setq cleared (ledger-toggle-current 'pending)))
+ (goto-char (cdr where))
+ (setq cleared (ledger-toggle-current-entry)))
(if cleared
- (add-text-properties (line-beginning-position)
- (line-end-position)
- (list 'face 'bold))
- (remove-text-properties (line-beginning-position)
- (line-end-position)
- (list 'face))))
- (forward-line)))
+ (add-text-properties (line-beginning-position)
+ (line-end-position)
+ (list 'face 'bold))
+ (remove-text-properties (line-beginning-position)
+ (line-end-position)
+ (list 'face))))
+ (forward-line)
+ (ledger-display-balance)))
(defun ledger-reconcile-refresh ()
(interactive)
@@ -62,7 +69,7 @@
(defun ledger-reconcile-delete ()
(interactive)
(let ((where (get-text-property (point) 'where)))
- (when (or (equal (car where) "<stdin>") (equal (car where) "/dev/stdin"))
+ (when (is-stdin (car where))
(with-current-buffer ledger-buf
(goto-char (cdr where))
(ledger-delete-current-entry))
@@ -74,7 +81,7 @@
(defun ledger-reconcile-visit ()
(interactive)
(let ((where (get-text-property (point) 'where)))
- (when (or (equal (car where) "<stdin>") (equal (car where) "/dev/stdin"))
+ (when (is-stdin (car where))
(switch-to-buffer-other-window ledger-buf)
(goto-char (cdr where)))))
@@ -97,7 +104,7 @@
(let ((where (get-text-property (point) 'where))
(face (get-text-property (point) 'face)))
(if (and (eq face 'bold)
- (or (equal (car where) "<stdin>") (equal (car where) "/dev/stdin")))
+ (when (is-stdin (car where))))
(with-current-buffer ledger-buf
(goto-char (cdr where))
(ledger-toggle-current 'cleared))))
@@ -105,45 +112,48 @@
(ledger-reconcile-save))
(defun ledger-do-reconcile ()
- (let* ((buf ledger-buf)
+ "get the uncleared transactions in the account and display them in the *Reconcile* buffer"
+ (let* ((buf ledger-buf)
(account ledger-acct)
(items
- (with-current-buffer
- (apply #'ledger-exec-ledger
- buf nil "emacs" account "--uncleared" '("--real"))
+ (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))))))
- (dolist (item items)
- (let ((index 1))
- (dolist (xact (nthcdr 5 item))
- (let ((beg (point))
- (where
- (with-current-buffer buf
- (cons
- (nth 0 item)
- (if ledger-clear-whole-entries
- (save-excursion
- (goto-line (nth 1 item))
- (point-marker))
- (save-excursion
- (goto-line (nth 0 xact))
- (point-marker)))))))
- (insert (format "%s %-30s %-25s %15s\n"
- (format-time-string "%m/%d" (nth 2 item))
- (nth 4 item) (nth 1 xact) (nth 2 xact)))
- (if (nth 3 xact)
- (set-text-properties beg (1- (point))
- (list 'face 'bold
- 'where where))
- (set-text-properties beg (1- (point))
- (list 'where where))))
- (setq index (1+ index)))))
- (goto-char (point-min))
- (set-buffer-modified-p nil)
- (toggle-read-only t)))
+ (read (current-buffer))))))
+ (dolist (item items)
+ (let ((index 1))
+ (dolist (xact (nthcdr 5 item))
+ (let ((beg (point))
+ (where
+ (with-current-buffer buf
+ (cons
+ (nth 0 item)
+ (if ledger-clear-whole-entries
+ (save-excursion
+ (goto-line (nth 1 item))
+ (point-marker))
+ (save-excursion
+ (goto-line (nth 0 xact))
+ (point-marker)))))))
+ (insert (format "%s %-4s %-30s %-30s %15s\n"
+ (format-time-string "%Y/%m/%d" (nth 2 item))
+ (nth 3 item)
+ (nth 4 item) (nth 1 xact) (nth 2 xact)))
+ (if (nth 3 xact)
+ (set-text-properties beg (1- (point))
+ (list 'face 'bold
+ 'where where))
+ (set-text-properties beg (1- (point))
+ (list 'where where))))
+ (setq index (1+ index)))))
+ (goto-char (point-min))
+ (set-buffer-modified-p nil)
+ (toggle-read-only t)))
+
(defun ledger-reconcile (account)
(interactive "sAccount to reconcile: ")
@@ -176,4 +186,20 @@
(define-key map [?p] 'previous-line)
(define-key map [?s] 'ledger-reconcile-save)
(define-key map [?q] 'ledger-reconcile-quit)
+
+ (define-key map [menu-bar] (make-sparse-keymap "ldg-recon-menu"))
+ (define-key map [menu-bar ldg-recon-menu] (cons "Reconcile" map))
+ (define-key map [menu-bar ldg-recon-menu qui] '("Quit" . ledger-reconcile-quit))
+ (define-key map [menu-bar ldg-recon-menu sep1] '("--"))
+ (define-key map [menu-bar ldg-recon-menu pre] '("Previous Entry" . previous-line))
+ (define-key map [menu-bar ldg-recon-menu vis] '("Visit Entry" . ledger-reconcile-visit))
+ (define-key map [menu-bar ldg-recon-menu nex] '("Next Entry" . next-line))
+ (define-key map [menu-bar ldg-recon-menu sep2] '("--"))
+ (define-key map [menu-bar ldg-recon-menu del] '("Delete Entry" . ledger-reconcile-delete))
+ (define-key map [menu-bar ldg-recon-menu add] '("Add Entry" . ledger-reconcile-add))
+ (define-key map [menu-bar ldg-recon-menu tog] '("Toggle Entry" . ledger-reconcile-toggle))
+ (define-key map [menu-bar ldg-recon-menu sep3] '("--"))
+ (define-key map [menu-bar ldg-recon-menu ref] '("Refresh" . ledger-reconcile-refresh))
+ (define-key map [menu-bar ldg-recon-menu sav] '("Save" . ledger-reconcile-save))
+
(use-local-map map)))
diff --git a/lisp/ldg-report.el b/lisp/ldg-report.el
index f9c6afca..efd9bdb4 100644
--- a/lisp/ldg-report.el
+++ b/lisp/ldg-report.el
@@ -70,6 +70,21 @@ text that should replace the format specifier."
(define-key map [(control ?c) (control ?l) (control ?e)]
'ledger-report-edit)
(define-key map [(control ?c) (control ?c)] 'ledger-report-visit-source)
+
+
+ (define-key map [menu-bar] (make-sparse-keymap "ldg-rep"))
+ (define-key map [menu-bar ldg-rep] (cons "Reports" map))
+
+ (define-key map [menu-bar ldg-rep lrq] '("Quit" . ledger-report-quit))
+ (define-key map [menu-bar ldg-rep s2] '("--"))
+ (define-key map [menu-bar ldg-rep lrd] '("Scroll Down" . scroll-down))
+ (define-key map [menu-bar ldg-rep lru] '("Scroll Up" . scroll-up))
+ (define-key map [menu-bar ldg-rep s1] '("--"))
+ (define-key map [menu-bar ldg-rep lrk] '("Kill Report" . ledger-report-kill))
+ (define-key map [menu-bar ldg-rep lrr] '("Re-run Report" . ledger-report-redo))
+ (define-key map [menu-bar ldg-rep lre] '("Edit Report" . ledger-report-edit))
+ (define-key map [menu-bar ldg-rep lrs] '("Save Report" . ledger-report-save))
+
(use-local-map map)))
(defun ledger-report-read-name ()
diff --git a/src/output.cc b/src/output.cc
index f433f8d1..6ed7f861 100644
--- a/src/output.cc
+++ b/src/output.cc
@@ -318,6 +318,34 @@ void report_payees::operator()(post_t& post)
(*i).second++;
}
+void report_tags::flush()
+{
+ std::ostream& out(report.output_stream);
+
+ foreach (tags_pair& entry, tags) {
+ if (report.HANDLED(count))
+ out << entry.second << ' ';
+ out << entry.first << '\n';
+ }
+}
+
+void report_tags::operator()(post_t& post)
+{
+ if(post.metadata){
+ foreach (const item_t::string_map::value_type& data, *post.metadata){
+ string tag=data.first;
+ if(report.HANDLED(values) && (data.second).first){
+ tag+=": "+ (data.second).first.get().to_string();
+ }
+ std::map<string, std::size_t>::iterator i = tags.find(tag);
+ if (i == tags.end())
+ tags.insert(tags_pair(tag, 1));
+ else
+ (*i).second++;
+ }
+ }
+}
+
void report_commodities::flush()
{
std::ostream& out(report.output_stream);
diff --git a/src/output.h b/src/output.h
index 281f69b6..9895cb44 100644
--- a/src/output.h
+++ b/src/output.h
@@ -189,6 +189,33 @@ public:
}
};
+class report_tags : public item_handler<post_t>
+{
+protected:
+ report_t& report;
+
+ std::map<string, std::size_t> tags;
+
+ typedef std::map<string, std::size_t>::value_type tags_pair;
+
+public:
+ report_tags(report_t& _report) : report(_report) {
+ TRACE_CTOR(report_tags, "report&");
+ }
+ virtual ~report_tags() {
+ TRACE_DTOR(report_tags);
+ }
+
+ virtual void flush();
+ virtual void operator()(post_t& post);
+
+ virtual void clear() {
+ tags.clear();
+ item_handler<post_t>::clear();
+ }
+};
+
+
class report_commodities : public item_handler<post_t>
{
protected:
diff --git a/src/report.cc b/src/report.cc
index d4beaf2a..f7b71b94 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -1089,7 +1089,6 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(anon);
else OPT_ALT(color, ansi);
else OPT(auto_match);
- else OPT(aux_date);
else OPT(average);
else OPT(account_width_);
else OPT(amount_width_);
@@ -1097,7 +1096,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
case 'b':
OPT(balance_format_);
else OPT(base);
- else OPT(basis);
+ else OPT_ALT(basis, cost);
else OPT_(begin_);
else OPT(bold_if_);
else OPT(budget);
@@ -1106,7 +1105,6 @@ option_t<report_t> * report_t::lookup_option(const char * p)
break;
case 'c':
OPT(csv_format_);
- else OPT_ALT(gain, change);
else OPT(cleared);
else OPT(collapse);
else OPT(collapse_if_zero);
@@ -1124,7 +1122,6 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(dc);
else OPT(depth_);
else OPT(deviation);
- else OPT_ALT(rich_data, detail);
else OPT_(display_);
else OPT(display_amount_);
else OPT(display_total_);
@@ -1149,7 +1146,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT_ALT(head_, first_);
break;
case 'g':
- OPT(gain);
+ OPT_ALT(gain, change);
else OPT(group_by_);
else OPT(group_title_format_);
else OPT(generated);
@@ -1176,7 +1173,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT_ALT(tail_, last_);
break;
case 'm':
- OPT(market);
+ OPT_ALT(market, value);
else OPT(monthly);
else OPT(meta_);
else OPT(meta_width_);
@@ -1206,7 +1203,6 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(price);
else OPT(prices_format_);
else OPT(pricedb_format_);
- else OPT(primary_date);
else OPT(payee_width_);
else OPT(prepend_format_);
else OPT(prepend_width_);
@@ -1224,7 +1220,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(revalued);
else OPT(revalued_only);
else OPT(revalued_total_);
- else OPT(rich_data);
+ else OPT_ALT(rich_data, detail);
break;
case 's':
OPT(sort_);
@@ -1252,7 +1248,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(unround);
break;
case 'v':
- OPT_ALT(market, value);
+ OPT(values);
break;
case 'w':
OPT(weekly);
@@ -1670,7 +1666,11 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
else if (is_eq(p, "select"))
return WRAP_FUNCTOR(select_command);
break;
-
+ case 't':
+ if (is_eq(p, "tags")) {
+ return POSTS_REPORTER(new report_tags(*this));
+ }
+ break;
case 'x':
if (is_eq(p, "xact"))
return WRAP_FUNCTOR(xact_command);
diff --git a/src/report.h b/src/report.h
index 2eac61fe..b0044f60 100644
--- a/src/report.h
+++ b/src/report.h
@@ -358,6 +358,7 @@ public:
HANDLER(account_width_).report(out);
HANDLER(amount_width_).report(out);
HANDLER(total_width_).report(out);
+ HANDLER(values).report(out);
}
option_t<report_t> * lookup_option(const char * p);
@@ -1043,6 +1044,7 @@ public:
OPTION(report_t, account_width_);
OPTION(report_t, amount_width_);
OPTION(report_t, total_width_);
+ OPTION(report_t, values);
};
template <class Type = post_t,