Merge remote-tracking branch 'origin/next'

This commit is contained in:
John Wiegley 2013-04-29 16:38:48 -05:00
commit c4853dcfd8
15 changed files with 4172 additions and 3384 deletions

View file

@ -101,7 +101,7 @@ following packages (current as of Ubuntu 12.04):
python-dev gettext libgmp3-dev libmpfr-dev libboost-dev
libboost-regex-dev libboost-date-time-dev
libboost-filesystem-dev libboost-python-dev texinfo lcov
sloccount
sloccount libboost-iostreams-dev libboost-test-dev
Or, for Ubuntu Karmic:

47
acprep
View file

@ -206,7 +206,7 @@ class CommandLineApp(object):
except KeyboardInterrupt:
exit_code = self.handleInterrupt()
except SystemExit, msg:
except SystemExit as msg:
exit_code = msg.args[0]
except Exception:
@ -244,7 +244,7 @@ class PrepareBuild(CommandLineApp):
}
for varname in self.envvars.keys():
if os.environ.has_key(varname):
if varname in os.environ:
self.envvars[varname] = os.environ[varname]
if varname.endswith('FLAGS'):
@ -327,7 +327,7 @@ class PrepareBuild(CommandLineApp):
if args:
cmd = args[0]
if not PrepareBuild.__dict__.has_key('phase_' + cmd):
if 'phase_' + cmd not in PrepareBuild.__dict__:
self.log.error("Unknown build phase: " + cmd + "\n")
sys.exit(1)
else:
@ -344,22 +344,22 @@ class PrepareBuild(CommandLineApp):
def execute(self, *args):
try:
self.log.debug('Executing command: ' + string.join(args, ' '))
self.log.debug('Executing command: ' + ' '.join(args))
retcode = call(args, shell=False)
if retcode < 0:
self.log.error("Child was terminated by signal", -retcode)
sys.exit(1)
elif retcode != 0:
self.log.error("Execution failed: " + string.join(args, ' '))
self.log.error("Execution failed: " + ' '.join(args))
sys.exit(1)
except OSError, e:
self.log.error("Execution failed:", e)
except OSError as e:
self.log.error("Execution failed: " + e)
sys.exit(1)
def get_stdout(self, *args):
try:
self.log.debug('Executing command: ' + string.join(args, ' '))
self.log.debug('Executing command: ' + ' '.join(args))
proc = Popen(args, shell=False, stdout=PIPE)
stdout = proc.stdout.read()
@ -369,11 +369,11 @@ class PrepareBuild(CommandLineApp):
-retcode)
sys.exit(1)
elif retcode != 0:
self.log.error("Execution failed: " + string.join(args, ' '))
self.log.error("Execution failed: " + ' '.join(args))
sys.exit(1)
return stdout[:-1]
except OSError, e:
self.log.error("Execution failed:", e)
except OSError as e:
self.log.error("Execution failed:" + e)
sys.exit(1)
def isnewer(self, file1, file2):
@ -452,7 +452,7 @@ class PrepareBuild(CommandLineApp):
def phase_products(self, *args):
self.log.info('Executing phase: products')
print self.products_directory()
print(self.products_directory())
def phase_info(self, *args):
self.log.info('Executing phase: info')
@ -527,7 +527,7 @@ class PrepareBuild(CommandLineApp):
'texlive-xetex', 'doxygen', 'graphviz', 'texinfo',
'lcov', 'sloccount'
] + BoostInfo.dependencies('darwin')
self.log.info('Executing: ' + string.join(packages, ' '))
self.log.info('Executing: ' + ' '.join(packages))
self.execute(*packages)
elif exists('/sw/bin/fink'):
self.log.info('Looks like you are using Fink on OS X')
@ -616,7 +616,7 @@ class PrepareBuild(CommandLineApp):
self.log.info('I do not recognize your version of Ubuntu!')
packages = None
if packages:
self.log.info('Executing: ' + string.join(packages, ' '))
self.log.info('Executing: ' + ' '.join(packages))
self.execute(*packages)
if exists('/etc/redhat-release'):
@ -646,7 +646,7 @@ class PrepareBuild(CommandLineApp):
#'lcov',
#'sloccount'
]
self.log.info('Executing: ' + string.join(packages, ' '))
self.log.info('Executing: ' + ' '.join(packages))
self.execute(*packages)
#########################################################################
@ -678,7 +678,7 @@ class PrepareBuild(CommandLineApp):
self.configure_args.append(self.source_dir)
def setup_for_system(self):
system = self.get_stdout('uname', '-s')
system = str(self.get_stdout('uname', '-s'))
self.log.info('System type is => ' + system)
if self.options.enable_doxygen:
@ -695,8 +695,7 @@ class PrepareBuild(CommandLineApp):
def setup_flavor(self):
self.setup_for_system()
if not PrepareBuild.__dict__.has_key('setup_flavor_' +
self.current_flavor):
if 'setup_flavor_' + self.current_flavor not in PrepareBuild.__dict__:
self.log.error('Unknown build flavor "%s"' % self.current_flavor)
sys.exit(1)
@ -725,7 +724,7 @@ class PrepareBuild(CommandLineApp):
self.log.debug('Final value of %s: %s' %
(var, self.envvars[var]))
elif self.envvars.has_key(var):
elif var in self.envvars:
del self.envvars[var]
#########################################################################
@ -795,8 +794,8 @@ class PrepareBuild(CommandLineApp):
sys.exit(1)
for var in ('CXX', 'CXXFLAGS', 'LDFLAGS'):
if self.envvars.has_key(var) and self.envvars[var] and \
(var.endswith('FLAGS') or exists(self.envvars[var])):
if self.envvars.get(var) and (var.endswith('FLAGS')
or exists(self.envvars[var])):
if var == 'CXX':
conf_args.append('-DCMAKE_CXX_COMPILER=%s' %
self.envvars[var])
@ -848,7 +847,7 @@ class PrepareBuild(CommandLineApp):
self.log.error("Child was terminated by signal", -retcode)
sys.exit(1)
elif retcode != 0:
self.log.error("Execution failed: " + string.join(conf_args, ' '))
self.log.error("Execution failed: " + ' '.join(conf_args))
sys.exit(1)
else:
self.log.debug('configure does not need to be run')
@ -1031,7 +1030,7 @@ class PrepareBuild(CommandLineApp):
def phase_help(self, *args):
self.option_parser.print_help()
print """
print("""
Of the optional ARGS, the first is an optional build FLAVOR, with the default
being 'debug':
@ -1077,7 +1076,7 @@ Here are some real-world examples:
./acprep
./acprep --python
./acprep opt make
./acprep make doc -- -DBUILD_WEB_DOCS=1"""
./acprep make doc -- -DBUILD_WEB_DOCS=1""")
sys.exit(0)
PrepareBuild().run()

View file

@ -0,0 +1,91 @@
### Assumption
#
# bash-completion package is installed and enabled
#
### Just want to try it?
#
# $ source ledger-completion.bash
#
### How to install?
#
#### For local user
#
# $ cat <<EOF >>~/.bash_completion
# . ~/.bash_completion.d/ledger
# EOF
#
# $ cp ledger-completion.bash ~/.bash_completion.d/ledger
#
#### For all users
#
# $ sudo cp ledger-completion.bash /etc/bash_completion.d/ledger
#
_ledger()
{
local cur prev command options
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# COMMANDS
#
# Commands are found in source code:
# report.cc::lookup "case symbol_t::COMMAND"
# report.cc::lookupcase "case symbol_t::PRECOMMAND" : these are debug commands and they have been filtered out here
#
commands="accounts balance budget cleared commodities convert csv draft echo emacs entry equity lisp org payees pricemap prices pricesdb print register reload select source stats tags xact xml"
# OPTIONS
#
# Options are found in source code:
# global.cc::lookup_option
# report.cc::lookup_option
# session.cc::lookup_option
#
options="--abbrev-len= --account-width= --account= --actual --actual-dates --add-budget --amount-data --amount-width= --amount= --anon --ansi --args-only --auto-match --aux-date --average --balance-format= --base --basis --begin= --bold-if= --budget --budget-format= --by-payee --cache= --change --check-payees --cleared --cleared-format= --collapse --collapse-if-zero --color --columns= --cost --count --csv-format= --current --daily --date-format= --date-width= --date= --datetime-format= --day-break --days-of-week --dc --debug= --decimal-comma --depth= --detail --deviation --display-amount= --display-total= --display= --dow --download --effective --empty --end= --equity --exact --exchange= --explicit --file= --first= --flat --force-color --force-pager --forecast-years= --forecast= --format= --full-help --gain --generated --group-by= --group-title-format= --head= --help --help-calc --help-comm --help-disp --historical --immediate --init-file= --inject= --input-date-format= --invert --last= --leeway= --limit= --lot-dates --lot-notes --lot-prices --lot-tags --lots --lots-actual --market --master-account= --meta-width= --meta= --monthly --no-color --no-rounding --no-titles --no-total --now= --only= --options --output= --pager= --payee-width= --payee= --pedantic --pending --percent --period-sort= --period= --permissive --pivot= --plot-amount-format= --plot-total-format= --prepend-format= --prepend-width= --price --price-db= --price-exp= --pricedb-format= --prices-format= --primary-date --quantity --quarterly --raw --real --register-format= --related --related-all --revalued --revalued-only --revalued-total= --rich-data --script= --seed= --sort-all= --sort-xacts= --sort= --start-of-week= --strict --subtotal --tail= --time-colon --time-report --total-data --total-width= --total= --trace= --truncate= --unbudgeted --uncleared --unrealized --unrealized-gains= --unrealized-losses= --unround --value --value-expr= --values --verbose --verify --verify-memory --version --weekly --wide --yearly"
# Bash FAQ E13 http://tiswww.case.edu/php/chet/bash/FAQ
#
COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
# ACCOUNTS
#
# Accounts are generated with bash command:
# $ ledger accounts>/tmp/accounts; for i in {1..5}; do cut -d : -f $i- /tmp/accounts;cut -d : -f -$i /tmp/accounts; done|sort -u|xargs
#
# Warning: this is working badly if there are spaces in account names
#
accounts="Assets Liabilities Equity Revenue Expenses"
case $prev in
--@(cache|file|init-file|output|pager|price-db|script))
_filedir
return 0
;;
@(balance|equity|print|register))
COMPREPLY=( $(compgen -W "${accounts}" -- ${cur}) )
return 0
;;
esac
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
# elif [[ ${cur} == [A-Z]* ]] ; then
# COMPREPLY=( $(compgen -W "${accounts}" -- ${cur}) )
else
COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
fi
return 0
}
complete -F _ledger ledger
# Local variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indent-comment: t
# indent-tabs-mode: nil
# End:
# ex: ts=4 sw=4 et filetype=sh

View file

@ -233,7 +233,11 @@ automatically place any amounts such that their last digit is aligned to
the column specified by @code{ledger-post-amount-alignment-column},
which defaults to 52. @xref{Ledger Post Customization Group}.
@node Quick Balance Display
@menu
* Quick Balance Display::
@end menu
@node Quick Balance Display, , Adding Transactions, Adding Transactions
@subsection Quick Balance Display
You will often want to quickly check the balance of an account. The
easiest way it to position point on the account you are interested in,

File diff suppressed because it is too large Load diff

View file

@ -36,10 +36,10 @@
(defun ledger-split-commodity-string (str)
"Split a commoditized string, STR, into two parts.
Returns a list with (value commodity)."
(if (> (length str) 0)
(let ((number-regex (if (assoc "decimal-comma" ledger-environment-alist)
ledger-amount-decimal-comma-regex
ledger-amount-decimal-period-regex)))
(if (> (length str) 0)
(with-temp-buffer
(insert str)
(goto-char (point-min))
@ -48,38 +48,35 @@ Returns a list with (value commodity)."
(let ((com (delete-and-extract-region
(match-beginning 1)
(match-end 1))))
(if (re-search-forward number-regex nil t)
(if (re-search-forward
number-regex nil t)
(list
(string-to-number
(ledger-commodity-string-number-decimalize
(delete-and-extract-region (match-beginning 0) (match-end 0)) :from-user))
(ledger-string-to-number
(delete-and-extract-region (match-beginning 0) (match-end 0)))
com))))
((re-search-forward number-regex nil t)
;; found a number in the current locale, return it in
;; the car. Anything left over is annotation,
;; the first thing should be the commodity, separated
;; by whitespace, return it in the cdr. I can't think of any
;; counterexamples
;; found a number in the current locale, return it in the
;; car. Anything left over is annotation, the first
;; thing should be the commodity, separated by
;; whitespace, return it in the cdr. I can't think of
;; any counterexamples
(list
(string-to-number
(ledger-commodity-string-number-decimalize
(delete-and-extract-region (match-beginning 0) (match-end 0)) :from-user))
(ledger-string-to-number
(delete-and-extract-region (match-beginning 0) (match-end 0)))
(nth 0 (split-string (buffer-substring-no-properties (point-min) (point-max))))))
((re-search-forward "0" nil t)
;; couldn't find a decimal number, look for a single 0,
;; indicating account with zero balance
(list 0 ledger-reconcile-default-commodity)))))
(list 0 ledger-reconcile-default-commodity))))
;; nothing found, return 0
(list 0 ledger-reconcile-default-commodity)))
(list 0 ledger-reconcile-default-commodity))))
(defun ledger-string-balance-to-commoditized-amount (str)
"Return a commoditized amount (val, 'comm') from STR."
(let ((fields (split-string str "[\n\r]"))) ; break any balances
; with multi commodities
; into a list
(mapcar #'(lambda (str)
(ledger-split-commodity-string str))
fields)))
; break any balances with multi commodities into a list
(mapcar #'(lambda (st)
(ledger-split-commodity-string st))
(split-string str "[\n\r]")))
(defun -commodity (c1 c2)
"Subtract C2 from C1, ensuring their commodities match."
@ -93,40 +90,39 @@ Returns a list with (value commodity)."
(list (+ (car c1) (car c2)) (cadr c1))
(error "Can't add different commodities, %S to %S" c1 c2)))
(defun ledger-commodity-string-number-decimalize (number-string direction)
"Take NUMBER-STRING and ensure proper decimalization for use by string-to-number and number-to-string.
DIRECTION can be :to-user or :from-user. All math calculations
are done with decimal-period, some users may prefer decimal-comma
which must be translated both directions."
(let ((val number-string))
(if (assoc "decimal-comma" ledger-environment-alist)
(cond ((eq direction :from-user)
;; change string to decimal-period
(while (string-match "," val)
(setq val (replace-match "." nil nil val)))) ;; switch to period separator
((eq direction :to-user)
;; change to decimal-comma
(while (string-match "\\." val)
(setq val (replace-match "," nil nil val)))) ;; gets rid of periods
(t
(error "ledger-commodity-string-number-decimalize: direction not properly specified %S" direction)))
(while (string-match "," val)
(setq val (replace-match "" nil nil val))))
val))
(defun ledger-strip (str char)
(let (new-str)
(concat (dolist (ch (append str nil) new-str)
(unless (= ch char)
(setq new-str (append new-str (list ch))))))))
(defun ledger-string-to-number (str &optional decimal-comma)
"improve builtin string-to-number by handling internationalization, and return nil of number can't be parsed"
(let ((nstr (if (or decimal-comma
(assoc "decimal-comma" ledger-environment-alist))
(ledger-strip str ?.)
(ledger-strip str ?,))))
(while (string-match "," nstr) ;if there is a comma now, it is a thousands separator
(setq nstr (replace-match "." nil nil nstr)))
(string-to-number nstr)))
(defun ledger-number-to-string (n &optional decimal-comma)
(let ((str (number-to-string n)))
(if (or decimal-comma
(assoc "decimal-comma" ledger-environment-alist))
(while (string-match "\\." str)
(setq str (replace-match "," nil nil str)))
str)))
(defun ledger-commodity-to-string (c1)
"Return string representing C1.
Single character commodities are placed ahead of the value,
longer ones are after the value."
(let ((val (ledger-commodity-string-number-decimalize
(number-to-string (car c1)) :to-user))
(let ((str (ledger-number-to-string (car c1)))
(commodity (cadr c1)))
(if (> (length commodity) 1)
(concat val " " commodity)
(concat commodity " " val))))
(concat str " " commodity)
(concat commodity " " str))))
(defun ledger-read-commodity-string (prompt)
(let ((str (read-from-minibuffer

View file

@ -38,6 +38,11 @@
(point)))
(end (point))
begins args)
;; to support end of line metadata
(save-excursion
(when (search-backward ";"
(line-beginning-position) t)
(setq begin (match-beginning 0))))
(save-excursion
(goto-char begin)
(when (< (point) end)
@ -73,7 +78,7 @@ Return tree structure"
(save-excursion
(goto-char (point-min))
(while (re-search-forward
ledger-account-any-status-regex nil t)
ledger-account-or-metadata-regex nil t)
(unless (and (>= origin (match-beginning 0))
(< origin (match-end 0)))
(setq account-elements
@ -90,6 +95,21 @@ Return tree structure"
(setq account-elements (cdr account-elements)))))))
account-tree))
(defun ledger-find-metadata-in-buffer ()
"Search through buffer and build list of metadata.
Return list."
(let ((origin (point)) accounts)
(save-excursion
(setq ledger-account-tree (list t))
(goto-char (point-min))
(while (re-search-forward
ledger-metadata-regex
nil t)
(unless (and (>= origin (match-beginning 0))
(< origin (match-end 0)))
(setq accounts (cons (match-string-no-properties 2) accounts)))))
accounts))
(defun ledger-accounts ()
"Return a tree of all accounts in the buffer."
(let* ((current (caar (ledger-parse-arguments)))
@ -104,6 +124,7 @@ Return tree structure"
root (cdr xact))
(setq root nil elements nil)))
(setq elements (cdr elements)))
(setq root (delete (list (car elements) t) root))
(and root
(sort
(mapcar (function
@ -124,9 +145,12 @@ Return tree structure"
(if (eq (save-excursion
(ledger-thing-at-point)) 'transaction)
(if (null current-prefix-arg)
(ledger-payees-in-buffer) ;; this completes against payee names
(delete
(caar (ledger-parse-arguments))
(ledger-payees-in-buffer)) ;; this completes against payee names
(progn
(let ((text (buffer-substring-no-properties (line-beginning-position)
(let ((text (buffer-substring-no-properties
(line-beginning-position)
(line-end-position))))
(delete-region (line-beginning-position)
(line-end-position))
@ -157,7 +181,7 @@ Does not use ledger xact"
(setq rest-of-name (match-string 3))
;; Start copying the postings
(forward-line)
(while (looking-at ledger-account-any-status-regex)
(while (looking-at ledger-account-or-metadata-regex)
(setq xacts (cons (buffer-substring-no-properties
(line-beginning-position)
(line-end-position))

View file

@ -113,8 +113,9 @@
(defvar ledger-font-lock-keywords
`( ;; (,ledger-other-entries-regex 1
;; ledger-font-other-face)
(,ledger-comment-regex 2
(,ledger-comment-regex 0
'ledger-font-comment-face)
(,ledger-multiline-comment-regex 0 'ledger-font-comment-face)
(,ledger-payee-pending-regex 2
'ledger-font-payee-pending-face) ; Works
(,ledger-payee-cleared-regex 2
@ -131,6 +132,33 @@
'ledger-font-other-face))
"Expressions to highlight in Ledger mode.")
(defun ledger-extend-region-multiline-comment ()
"Adjusts the variables font-lock-beg and font-lock-end if they
fall within a multiline comment. Returns non-nil if an
adjustment is made."
(let (beg end)
;; fix beg
(save-excursion
(goto-char font-lock-beg)
(end-of-line)
(when (re-search-backward ledger-multiline-comment-start-regex nil t)
(setq beg (point))
(re-search-forward ledger-multiline-comment-regex nil t)
(if (and (>= (point) font-lock-beg)
(/= beg font-lock-beg))
(setq font-lock-beg beg)
(setq beg nil))))
;; fix end
(save-excursion
(goto-char font-lock-end)
(end-of-line)
(when (re-search-backward ledger-multiline-comment-start-regex nil t)
(re-search-forward ledger-multiline-comment-regex nil t)
(setq end (point))
(if (> end font-lock-end)
(setq font-lock-end end)
(setq end nil))))
(or beg end)))
(provide 'ldg-fonts)

View file

@ -68,13 +68,21 @@ And calculate the target-delta of the account being reconciled."
(message balance))))
(defun ledger-magic-tab (&optional interactively)
"Decide what to with with <TAB> .
Can be pcomplete, or align-posting"
"Decide what to with with <TAB>.
Can indent, complete or align depending on context."
(interactive "p")
(if (and (> (point) 1)
(looking-back "[:A-Za-z0-9]" 1))
(ledger-pcomplete interactively)
(ledger-post-align-postings)))
(when (= (point) (line-end-position))
(if (= (point) (line-beginning-position))
(indent-to ledger-post-account-alignment-column)
(save-excursion
(re-search-backward
(rx-static-or ledger-account-any-status-regex
ledger-metadata-regex
ledger-payee-any-status-regex)
(line-beginning-position) t))
(when (= (point) (match-end 0))
(ledger-pcomplete interactively))))
(ledger-post-align-postings))
(defvar ledger-mode-abbrev-table)
@ -102,6 +110,10 @@ Can be pcomplete, or align-posting"
(if (boundp 'font-lock-defaults)
(set (make-local-variable 'font-lock-defaults)
'(ledger-font-lock-keywords nil t)))
(setq font-lock-extend-region-functions
(list #'font-lock-extend-region-wholelines
#'ledger-extend-region-multiline-comment))
(setq font-lock-multiline nil)
(set (make-local-variable 'pcomplete-parse-arguments-function)
'ledger-parse-arguments)

View file

@ -59,7 +59,7 @@
"A list of currently active overlays to the ledger buffer.")
(make-variable-buffer-local 'ledger-occur-overlay-list)
(defun ledger-remove-all-overlays ()
(defun ledger-occur-remove-all-overlays ()
"Remove all overlays from the ledger buffer."
(interactive)
(remove-overlays))
@ -130,8 +130,7 @@ When REGEX is nil, unhide everything, and remove higlight"
buffer-matches))))
(mapcar (lambda (ovl)
(overlay-put ovl ledger-occur-overlay-property-name t)
(overlay-put ovl 'invisible t)
(overlay-put ovl 'intangible t))
(overlay-put ovl 'invisible t))
(push (make-overlay (cadr (car(last buffer-matches)))
(point-max)
(current-buffer) t nil) overlays)))))

View file

@ -217,7 +217,7 @@ BEG, END, and LEN control how far it can align."
(let ((end-of-amount (re-search-forward "[-.,0-9]+" (line-end-position) t)))
;; determine if there is an amount to edit
(if end-of-amount
(let ((val (ledger-commodity-string-number-decimalize (match-string 0) :from-user)))
(let ((val (ledger-string-to-number (match-string 0))))
(goto-char (match-beginning 0))
(delete-region (match-beginning 0) (match-end 0))
(calc)

View file

@ -37,39 +37,59 @@
"-?[1-9][0-9.]*[,]?[0-9]*")
(defconst ledger-amount-decimal-period-regex
"-?[1-9][0-9.]*[.]?[0-9]*")
"-?[1-9][0-9,]*[.]?[0-9]*")
(defconst ledger-other-entries-regex
"\\(^[~=A-Za-z].+\\)+")
(defconst ledger-comment-regex
"\\( \\| \\|^\\)\\(;.*\\)")
"^[;#|\\*%].*\\|[ \t]+;.*")
(defconst ledger-multiline-comment-start-regex
"^!comment$")
(defconst ledger-multiline-comment-end-regex
"^!end_comment$")
(defconst ledger-multiline-comment-regex
"^!comment\n\\(.*\n\\)*?!end_comment$")
(defconst ledger-payee-any-status-regex
"^[0-9/.=-]+\\(\\s-+\\*\\)?\\(\\s-+(.*?)\\)?\\s-+\\(.+?\\)\\(\t\\|\n\\| [ \t]\\)")
"^[0-9]+[-/][-/.=0-9]+\\(\\s-+\\*\\)?\\(\\s-+(.*?)\\)?\\s-+\\(.+?\\)\\s-*\\(;\\|$\\)")
(defconst ledger-payee-pending-regex
"^[0-9]+[-/][-/.=0-9]+\\s-\\!\\s-+\\(([^)]+)\\s-+\\)?\\([^*].+?\\)\\(;\\|$\\)")
"^[0-9]+[-/][-/.=0-9]+\\s-\\!\\s-+\\(([^)]+)\\s-+\\)?\\([^*].+?\\)\\s-*\\(;\\|$\\)")
(defconst ledger-payee-cleared-regex
"^[0-9]+[-/][-/.=0-9]+\\s-\\*\\s-+\\(([^)]+)\\s-+\\)?\\([^*].+?\\)\\(;\\|$\\)")
"^[0-9]+[-/][-/.=0-9]+\\s-\\*\\s-+\\(([^)]+)\\s-+\\)?\\([^*].+?\\)\\s-*\\(;\\|$\\)")
(defconst ledger-payee-uncleared-regex
"^[0-9]+[-/][-/.=0-9]+\\s-+\\(([^)]+)\\s-+\\)?\\([^*].+?\\)\\(;\\|$\\)")
"^[0-9]+[-/][-/.=0-9]+\\s-+\\(([^)]+)\\s-+\\)?\\([^*].+?\\)\\s-*\\(;\\|$\\)")
(defconst ledger-init-string-regex
"^--.+?\\($\\|[ ]\\)")
(defconst ledger-account-any-status-regex
"^[ \t]+\\([*!]\\s-+\\)?\\([[(]?.+?\\)\\(\t\\|\n\\| [ \t]\\)")
"^[ \t]+\\(?1:[*!]\\s-*\\)?\\(?2:[^ ;].*?\\)\\( \\|\t\\|$\\)")
(defconst ledger-account-pending-regex
"\\(^[ \t]+\\)\\(!.+?\\)\\( \\|$\\)")
"\\(^[ \t]+\\)\\(!\\s-*.*?\\)\\( \\|\t\\|$\\)")
(defconst ledger-account-cleared-regex
"\\(^[ \t]+\\)\\(\\*.+?\\)\\( \\|$\\)")
"\\(^[ \t]+\\)\\(*\\s-*.*?\\)\\( \\|\t\\|$\\)")
(defconst ledger-metadata-regex
"[ \t]+\\(?2:;[ \t]+.+\\)$")
(defconst ledger-account-or-metadata-regex
(concat
ledger-account-any-status-regex
"\\|"
ledger-metadata-regex))
(defmacro rx-static-or (&rest rx-strs)
"Returns rx union of regexps which can be symbols that eval to strings."
`(rx (or ,@(mapcar #'(lambda (rx-str)
`(regexp ,(eval rx-str)))
rx-strs))))
(defmacro ledger-define-regexp (name regex docs &rest args)
"Simplify the creation of a Ledger regex and helper functions."

View file

@ -71,7 +71,13 @@
(interactive "r") ;; load beg and end from point and mark
;; automagically
(let ((new-beg beg)
(new-end end))
(new-end end)
point-delta
(bounds (ledger-find-xact-extents (point)))
target-xact)
(setq point-delta (- (point) (car bounds)))
(setq target-xact (buffer-substring (car bounds) (cadr bounds)))
(setq inhibit-modification-hooks t)
(save-excursion
(save-restriction
@ -93,14 +99,21 @@
'ledger-next-record-function
'ledger-end-record-function
'ledger-sort-startkey))))
(goto-char beg)
(re-search-forward (regexp-quote target-xact))
(goto-char (+ (match-beginning 0) point-delta))
(setq inhibit-modification-hooks nil)))
(defun ledger-sort-buffer ()
"Sort the entire buffer."
(interactive)
(let (sort-start
sort-end)
(save-excursion
(goto-char (point-min))
(let ((sort-start (ledger-sort-find-start))
(sort-end (ledger-sort-find-end)))
(setq sort-start (ledger-sort-find-start)
sort-end (ledger-sort-find-end)))
(ledger-sort-region (if sort-start
sort-start
(point-min))