summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-03-04 15:20:49 -0500
committerJohn Wiegley <johnw@newartisans.com>2010-03-04 15:20:49 -0500
commit3bb4cb6b6055f180112f357cf23463a1b8c186c5 (patch)
tree82c264de1672c7a3fa27d6934f869096817e78ee
parent547137096051ab985dca6f8e5c7be191b62ccb0c (diff)
parent9143fbcdf13eb1d3601b37e8d8a3cdccacb90df1 (diff)
downloadfork-ledger-3bb4cb6b6055f180112f357cf23463a1b8c186c5.tar.gz
fork-ledger-3bb4cb6b6055f180112f357cf23463a1b8c186c5.tar.bz2
fork-ledger-3bb4cb6b6055f180112f357cf23463a1b8c186c5.zip
Merge branch 'next'
-rw-r--r--contrib/vim/README2
-rw-r--r--contrib/vim/compiler/ledger.vim31
-rw-r--r--contrib/vim/syntax/ledger.vim25
-rw-r--r--lisp/ledger.el55
-rw-r--r--src/precmd.cc2
-rw-r--r--src/precmd.h2
-rw-r--r--src/report.cc6
7 files changed, 92 insertions, 31 deletions
diff --git a/contrib/vim/README b/contrib/vim/README
index 4da73ea6..368c9c71 100644
--- a/contrib/vim/README
+++ b/contrib/vim/README
@@ -2,7 +2,7 @@
This is the ledger filetype for vim.
Copy each file to the corresponding directory in your ~/.vim directory.
Then include the following line in your .vimrc or in ~/.vim/filetype.vim
- au BufNewFile,BufRead *.ldg,*.ledger setf ledger
+ au BufNewFile,BufRead *.ldg,*.ledger setf ledger | comp ledger
You can also use a modeline like this in every ledger file
vim:filetype=ledger
diff --git a/contrib/vim/compiler/ledger.vim b/contrib/vim/compiler/ledger.vim
new file mode 100644
index 00000000..33b019cb
--- /dev/null
+++ b/contrib/vim/compiler/ledger.vim
@@ -0,0 +1,31 @@
+" Vim Compiler File
+" Compiler: ledger
+" by Johann Klähn; Use according to the terms of the GPL>=2.
+" vim:ts=2:sw=2:sts=2:foldmethod=marker
+
+if exists("current_compiler")
+ finish
+endif
+let current_compiler = "ledger"
+
+if exists(":CompilerSet") != 2
+ command -nargs=* CompilerSet setlocal <args>
+endif
+
+if ! exists("g:ledger_bin") || ! executable(g:ledger_bin)
+ if executable('ledger')
+ let g:ledger_bin = 'ledger'
+ else
+ echoerr "ledger command not found. Set g:ledger_bin or extend $PATH."
+ finish
+ endif
+endif
+
+" %-G throws away blank lines, everything else is assumed to be part of a
+" multi-line error message.
+CompilerSet errorformat=%-G,%EWhile\ parsing\ file\ \"%f\"\\,\ line\ %l:%.%#,%ZError:\ %m,%C%.%#
+
+" unfortunately there is no 'check file' command,
+" so we will just use a query that returns no results. ever.
+exe 'CompilerSet makeprg='.g:ledger_bin.'\ -f\ %\ reg\ not\ ''.*''\ \>\ /dev/null'
+
diff --git a/contrib/vim/syntax/ledger.vim b/contrib/vim/syntax/ledger.vim
index 8914cf2a..c96e4c3c 100644
--- a/contrib/vim/syntax/ledger.vim
+++ b/contrib/vim/syntax/ledger.vim
@@ -24,26 +24,37 @@ endif
" for debugging
syntax clear
-
+
+" DATE[=EDATE] [*|!] [(CODE)] DESC <-- first line of transaction
+" ACCOUNT AMOUNT [; NOTE] <-- posting
+
" region: a transaction containing postings
syn region transNorm start=/^[[:digit:]~]/ skip=/^\s/ end=/^/
- \ fold keepend transparent contains=transDate, Metadata, Posting
+ \ fold keepend transparent contains=transDate,Metadata,Posting
syn match transDate /^\d\S\+/ contained
-syn match Metadata /^\s\+;.*/ contained
+syn match Metadata /^\s\+;.*/ contained contains=MetadataTag
syn match Comment /^;.*$/
" every space in an account name shall be surrounded by two non-spaces
" every account name ends with a tab, two spaces or the end of the line
syn match Account /^\s\+\zs\%(\S \S\|\S\)\+\ze\%([ ]\{2,}\|\t\s*\|\s*$\)/ contained
-syn match Posting /^\s\+[^[:blank:];].*$/ contained transparent contains=Account
+syn match Posting /^\s\+[^[:blank:];].*$/ contained transparent contains=Account,Amount
+" FIXME: add other symbols?
+let s:currency = '\([$€£¢]\|\w\+\)'
+let s:figures = '\d\+\([.,]\d\+\)*'
+let s:amount = '-\?\('.s:figures.'\s*'.s:currency.'\|'.s:currency.'\s*'.s:figures.'\)'
+exe 'syn match Amount /'.s:amount.'/ contained'
+syn match MetadataTag /:\zs[^:]\+\ze:\|;\s*\zs[^:]\+\ze:[^:]\+$/ contained
-highlight default link transDate Question
-highlight default link Metadata PreProc
+highlight default link transDate Constant
+highlight default link Metadata Tag
+highlight default link MetadataTag Type
+highlight default link Amount Number
highlight default link Comment Comment
highlight default link Account Identifier
" syncinc is easy: search for the first transaction.
syn sync clear
-syn sync match ledgerSync grouphere transNorm "^\d"
+syn sync match ledgerSync grouphere transNorm "^[[:digit:]~]"
let b:current_syntax = "ledger"
diff --git a/lisp/ledger.el b/lisp/ledger.el
index 8e4de270..c2407261 100644
--- a/lisp/ledger.el
+++ b/lisp/ledger.el
@@ -152,31 +152,46 @@ customizable to ease retro-entry.")
"Start a ledger session with the current month, but make it
customizable to ease retro-entry.")
+(defvar ledger-rx-constituents
+ (append (list (cons 'date
+ (rx (opt (group (= 4 digit)) (in "./"))
+ (group (1+ digit)) (in "./")
+ (group (1+ digit))))
+ (cons 'opt-mark
+ (rx (opt (group "*") (1+ blank)))))
+ rx-constituents))
+
+(defmacro ledger-rx (&rest body)
+ `(let ((rx-constituents ledger-rx-constituents))
+ (rx ,@body)))
+
+(defun ledger--iterate-dispatch (nyear nmonth nday nmark ndesc)
+ (let ((start (point))
+ (year (match-string nyear))
+ (month (string-to-number (match-string nmonth)))
+ (day (string-to-number (match-string nday)))
+ (mark (match-string nmark))
+ (desc (match-string ndesc)))
+ (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)))
+
(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)))))
+ (cond ((looking-at (rx "Y" (1+ blank) (group (1+ digit))))
+ (setq current-year (string-to-number (match-string 1))))
+
+ ((looking-at (ledger-rx date "=" date (1+ blank) opt-mark (group (1+ nonl))))
+ (ledger--iterate-dispatch 1 2 3 7 8))
+
+ ((looking-at (ledger-rx date (1+ blank) opt-mark (group (1+ nonl))))
+ (ledger--iterate-dispatch 1 2 3 4 5)))
(forward-line))))
(defun ledger-time-less-p (t1 t2)
diff --git a/src/precmd.cc b/src/precmd.cc
index 31249016..632caeae 100644
--- a/src/precmd.cc
+++ b/src/precmd.cc
@@ -174,7 +174,7 @@ value_t period_command(call_scope_t& args)
return NULL_VALUE;
}
-value_t args_command(call_scope_t& args)
+value_t query_command(call_scope_t& args)
{
report_t& report(find_scope<report_t>(args));
std::ostream& out(report.output_stream);
diff --git a/src/precmd.h b/src/precmd.h
index e0f81cf8..88d66ab2 100644
--- a/src/precmd.h
+++ b/src/precmd.h
@@ -52,7 +52,7 @@ value_t parse_command(call_scope_t& args);
value_t eval_command(call_scope_t& args);
value_t format_command(call_scope_t& args);
value_t period_command(call_scope_t& args);
-value_t args_command(call_scope_t& args);
+value_t query_command(call_scope_t& args);
} // namespace ledger
diff --git a/src/report.cc b/src/report.cc
index fa71e584..b882ca92 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -1272,7 +1272,7 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
switch (*p) {
case 'a':
if (is_eq(p, "args"))
- return WRAP_FUNCTOR(args_command);
+ return WRAP_FUNCTOR(query_command);
break;
case 'e':
if (is_eq(p, "eval"))
@@ -1294,6 +1294,10 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
else if (is_eq(p, "period"))
return WRAP_FUNCTOR(period_command);
break;
+ case 'q':
+ if (is_eq(p, "query"))
+ return WRAP_FUNCTOR(query_command);
+ break;
case 't':
if (is_eq(p, "template"))
return WRAP_FUNCTOR(template_command);