summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Bremner <bremner@debian.org>2019-09-07 14:13:47 -0300
committerDavid Bremner <bremner@debian.org>2019-09-07 14:13:47 -0300
commit7d4f69c3fc3fcc73e2004107e90ced5e0f0577a0 (patch)
treed4daefb63f35b940e20c1abe3b780f452565d6f8
parentcba56f9a4e1147ca042775a8bdd5f26724838014 (diff)
parent5067e40805c40e83424d206584838ffa8c8117c7 (diff)
Merge tag 'upstream/3.1.2_pre3+g5067e408'
-rw-r--r--.travis.yml66
-rw-r--r--doc/ledger-mode.texi89
-rw-r--r--ledger-commodities.el1
-rw-r--r--ledger-complete.el171
-rw-r--r--ledger-context.el2
-rw-r--r--ledger-exec.el29
-rw-r--r--ledger-flymake.el14
-rw-r--r--ledger-init.el7
-rw-r--r--ledger-mode.el20
-rw-r--r--ledger-navigate.el71
-rw-r--r--ledger-occur.el3
-rw-r--r--ledger-post.el22
-rw-r--r--ledger-reconcile.el2
-rw-r--r--ledger-regex.el26
-rw-r--r--ledger-report.el19
-rw-r--r--ledger-xact.el62
-rw-r--r--test/Makefile4
-rw-r--r--test/complete-test.el107
-rw-r--r--test/mode-test.el26
-rw-r--r--test/navigate-test.el28
-rw-r--r--test/reconcile-test.el2
-rw-r--r--test/test-helper.el5
-rwxr-xr-xtools/travis-install-ledger.sh48
23 files changed, 434 insertions, 390 deletions
diff --git a/.travis.yml b/.travis.yml
index edadf85..9209c46 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,64 +1,32 @@
sudo: required
-
language: generic
-
-cache:
- directories:
- - ledger-master
- - ledger-next
-
-os:
- - linux
- # - osx # Travis is saturated; see https://www.traviscistatus.com/
+dist: xenial
env:
matrix:
- - EMACS_VERSION=emacs24 LEDGER_BRANCH=master
- # - EMACS_VERSION=emacs24 LEDGER_BRANCH=apt-get # apt-get's ledger is too old
- - EMACS_VERSION=emacs-snapshot LEDGER_BRANCH=next
-
-matrix:
- allow_failures:
- - env: EMACS_VERSION=emacs-snapshot LEDGER_BRANCH=next
+ - EVM_EMACS=emacs-24.3-travis
+ - EVM_EMACS=emacs-25.1-travis
+ # EVM doesn't support xenial yet, which we need since it has ledger version 3.
+ # See https://github.com/rejeep/evm/issues/125
+ # - EVM_EMACS=emacs-26.1-travis
+ # - EVM_EMACS=emacs-26.2-travis
+ # - EVM_EMACS=emacs-git-snapshot-travis
before_install:
- - ./tools/travis-install-ledger.sh $LEDGER_BRANCH
- - if [ "$TRAVIS_OS_NAME" = "linux" ]; then
- export PATH=$TRAVIS_BUILD_DIR/ledger-$LEDGER_BRANCH:$PATH;
- fi
-
-install:
- - if [ "$TRAVIS_OS_NAME-$EMACS_VERSION" = "linux-emacs24" ]; then
- sudo add-apt-repository -y ppa:cassou/emacs &&
- sudo apt-get -qq update &&
- sudo apt-get -qq install emacs24 emacs24-el &&
- export EMACS=/usr/bin/emacs;
- fi
- - if [ "$TRAVIS_OS_NAME-$EMACS_VERSION" = "linux-emacs-snapshot" ]; then
- sudo add-apt-repository -y ppa:ubuntu-elisp/ppa &&
- sudo apt-get -qq update &&
- sudo apt-get -qq install emacs-snapshot &&
- export EMACS=/usr/bin/emacs-snapshot;
- fi
- - if [ "$TRAVIS_OS_NAME-$EMACS_VERSION" = "osx-emacs24" ]; then
- wget https://emacsformacosx.com/emacs-builds/Emacs-24.4-universal.dmg &&
- hdiutil attach Emacs-24.4-universal.dmg &&
- export EMACS=/Volumes/Emacs/Emacs.app/Contents/MacOS/Emacs;
- fi
- - if [ "$TRAVIS_OS_NAME-$EMACS_VERSION" = "osx-emacs25" ]; then
- wget https://emacsformacosx.com/emacs-builds/Emacs-25.1-universal.dmg &&
- hdiutil attach Emacs-25.1-universal.dmg &&
- export EMACS=/Volumes/Emacs/Emacs.app/Contents/MacOS/Emacs;
- fi
+ - sudo apt-get install -y ledger
+ - git clone https://github.com/rejeep/evm.git $HOME/.evm
+ - export PATH=$HOME/.evm/bin:$PATH
+ - evm config path /tmp
+ - evm install $EVM_EMACS --use --skip
script:
- - $EMACS --version
+ - emacs --version
- ledger --version
- - $EMACS --eval "(setq byte-compile-error-on-warn (>= emacs-major-version 25))" -L . --batch -f batch-byte-compile ledger-*.el
- - cd test && make test-batch EMACS="$EMACS"
+ - emacs --eval "(setq byte-compile-error-on-warn (>= emacs-major-version 25))" -L . --batch -f batch-byte-compile *.el
+ - make -C test test-batch
after_script:
- - make checkdoc
+ - make -C test checkdoc
notifications:
email: false
diff --git a/doc/ledger-mode.texi b/doc/ledger-mode.texi
index e47bdae..1a5674d 100644
--- a/doc/ledger-mode.texi
+++ b/doc/ledger-mode.texi
@@ -47,7 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@end copying
-@dircategory Major Modes
+@dircategory Emacs
@direntry
* Ledger Mode: (ledger-mode). Command-Line Accounting
@end direntry
@@ -169,18 +169,13 @@ format. Then type the first few characters of another payee in the
search for a Payee that has the same beginning and copy the rest of the
transaction to you new entry.
-Additionally you can use the ledger @command{xact} command, by either
-typing @kbd{C-c C-a} or using @samp{Add Transaction} menu entry. Then
-typing a close match to the payee. Ledger-mode will call @command{ledger
-xact} with the data you enter and place the transaction in the proper
-chronological place in the ledger.
-
-If you need to add a lot of transactions that are not near your current
-date you can set the current year and month so that using @samp{Add
-Transaction} will prompt you with a more convenient month and year. To
-set the month type @kbd{C-c RET} and enter the month you want. @kbd{C-c
-C-y} will prompt you for the year. These settings only effect the
-@samp{Add Transaction} command.
+Additionally you can use the ledger @command{xact} command, by either typing
+@kbd{C-c C-a} or using @samp{Add Transaction} menu entry. Then typing a close
+match to the payee. Ledger-mode will call @command{ledger xact} with the data
+you enter and place the transaction in the proper chronological place in the
+ledger. Subsequent calls to @kbd{C-c C-a} remember the last date so entering
+many dates in the past is easy. The date format can be changed by modifying
+@option{ledger-default-date-format}.
@node Reconciliation, Reports, Quick Add, Quick Demo
@subsection Reconciliation
@@ -254,6 +249,7 @@ current regex. Cancel the narrowing by typing @kbd{C-c C-f} again.
@chapter The Ledger Buffer
@menu
+* Navigating Transactions::
* Adding Transactions::
* Copying Transactions::
* Editing Amounts::
@@ -264,26 +260,59 @@ current regex. Cancel the narrowing by typing @kbd{C-c C-f} again.
* Narrowing Transactions::
@end menu
+@node Navigating Transactions, Adding Transactions, The Ledger Buffer, The Ledger Buffer
+@section Navigating Transactions
+@cindex transaction, navigation
+
+@findex ledger-navigate-next-xact-or-directive
+@findex ledger-navigate-prev-xact-or-directive
+@kindex M-p
+@kindex M-n
+
+In addition to the usual Emacs navigation commands, ledger-mode offers several
+additional commands to ease navigation. @kbd{M-n} and @kbd{M-p} navigate between
+next and previous xacts or directives.
-@node Adding Transactions, Copying Transactions, The Ledger Buffer, The Ledger Buffer
+@findex ledger-navigate-next-uncleared
+@findex ledger-navigate-previous-uncleared
+
+Additionally, M-x ledger-navigate-previous-uncleared and M-x
+ledger-navigate-next-uncleared navigate to the next and precious uncleared
+transactions.
+
+
+@node Adding Transactions, Copying Transactions, Navigating Transactions, The Ledger Buffer
@section Adding Transactions
-@findex ledger-post-auto-adjust-amounts
@findex ledger-post-amount-alignment-column
@kindex TAB
@cindex transaction, adding
Beyond the two ways of quickly adding transactions (@pxref{Quick Add})
-Ledger-mode assists you by providing robust @kbd{TAB} completion for
-payees and accounts. Ledger-mode will scan the existing buffer for
-payees and accounts. Included files are not currently included in the
-completion scan. Repeatedly hitting @kbd{TAB} will cycle through the
-possible completions.
-
-Ledger-mode can also help you keep your amounts aligned. Setting
-@option{ledger-post-auto-adjust-amounts} to true tells Ledger-mode to
-automatically place any amounts such that their last digit is aligned to
-the column specified by @option{ledger-post-amount-alignment-column},
-which defaults to @samp{52}. @xref{Ledger Post Customization Group}.
+Ledger-mode assists you by providing robust @kbd{TAB} completion for payees and
+accounts. Ledger-mode will scan the existing buffer for payees and accounts.
+Included files are not currently included in the completion scan. Ledger-mode
+respects Emacs's variables that govern @kbd{TAB} completion, see especially
+@code{tab-always-indent}.
+
+To cycle between completions when hitting @kbd{TAB} multiple times, you can
+adjust the standard completion configuration like this:
+
+@lisp
+(add-hook 'ledger-mode-hook
+ (lambda ()
+ (setq-local tab-always-indent 'complete)
+ (setq-local completion-cycle-threshold t)
+ (setq-local ledger-complete-in-steps t)))
+@end lisp
+
+Ledger-mode will help you keep your amounts aligned. When indenting or
+completing, Ledger-mode will automatically place any amounts such that their
+last digit is aligned to the column specified by
+@option{ledger-post-amount-alignment-column}, which defaults to
+@samp{52}. @xref{Ledger Post Customization Group}.
+
+To prevent the automatic realignment of amounts, disable
+@option{ledger-post-auto-align}. @xref{Ledger Post Customization Group}.
@menu
* Setting a Transactions Effective Date::
@@ -328,6 +357,10 @@ An easy way to copy a transaction is to type @kbd{C-c C-k} or menu entry
copied transaction, and after having confirmed with @kbd{RET}, new
transaction will be inserted at @emph{date} position in buffer.
+If you prefer to keep blank lines between your transactions, you can
+change the default in
+@option{ledger-copy-transaction-insert-blank-line-after}.
+
@node Editing Amounts, Marking Transactions, Copying Transactions, The Ledger Buffer
@section Editing Amounts
@kindex C-c C-b
@@ -1113,10 +1146,6 @@ Ledger Post:
@ftable @option
-@item ledger-post-auto-adjust-amounts
-If non-nil, then automatically align amounts to column specified in
-@option{ledger-post-amount-alignment-column}.
-
@item ledger-post-amount-alignment-column
The column Ledger-mode uses to align amounts.
diff --git a/ledger-commodities.el b/ledger-commodities.el
index 823f045..beb4759 100644
--- a/ledger-commodities.el
+++ b/ledger-commodities.el
@@ -31,6 +31,7 @@
;; These keep the byte-compiler from warning about them, but have no other
;; effect:
(defvar ledger-environment-alist)
+(declare-function ledger-exec-ledger "ledger-exec" (input-buffer &optional output-buffer &rest args))
(defcustom ledger-reconcile-default-commodity "$"
"The default commodity for use in target calculations in ledger reconcile."
diff --git a/ledger-complete.el b/ledger-complete.el
index 48199e7..569031e 100644
--- a/ledger-complete.el
+++ b/ledger-complete.el
@@ -22,17 +22,7 @@
;;; Commentary:
;; Functions providing payee and account auto complete.
-(require 'pcomplete)
(require 'cl-lib)
-(unless (fboundp 'pcomplete-uniquify-list)
- ;; TODO: Remove after dropping support for Emacs < 27
- (defalias 'pcomplete-uniquify-list 'pcomplete-uniqify-list))
-
-;; Emacs 24.3 compatibility
-(defun ledger-string-greaterp (string1 string2)
- "Return non-nil if STRING1 is greater than STRING2 in lexicographic order.
-Case is significant."
- (string-lessp string2 string1))
;; In-place completion support
@@ -47,11 +37,19 @@ This file will then be used as a source for account name completions."
:type 'file
:group 'ledger)
+(defcustom ledger-complete-in-steps nil
+ "When non-nil, `ledger-complete-at-point' completes account names in steps.
+If nil, full account names are offered for completion."
+ :type 'boolean
+ :group 'ledger
+ :package-version '(ledger-mode . "2019-05-27"))
+
(defun ledger-parse-arguments ()
"Parse whitespace separated arguments in the current region."
- ;; this is more complex than it appears to need, so that it can work
- ;; with pcomplete. See pcomplete-parse-arguments-function for
- ;; details
+ ;; FIXME: We don't use pcomplete anymore.
+ ;; This is more complex than it appears
+ ;; to need, so that it can work with pcomplete. See
+ ;; pcomplete-parse-arguments-function for details
(let* ((begin (save-match-data
(if (looking-back (concat "^\\(" ledger-iso-date-regexp "=\\|\\)"
ledger-incomplete-date-regexp) nil)
@@ -90,16 +88,7 @@ This file will then be used as a source for account name completions."
(setq payees-list (cons (match-string-no-properties 3)
payees-list))))) ;; add the payee
;; to the list
- (pcomplete-uniquify-list (nreverse payees-list))))
-
-(defun ledger-accounts-deduplicate-sorted (l)
- "Remove duplicates from a sorted list of strings L."
- (let ((current l))
- (while (consp current)
- (if (string= (car current) (cadr current))
- (setcdr current (cddr current))
- (pop current)))
- l))
+ (sort (delete-dups payees-list) #'string-lessp)))
(defun ledger-accounts-list-in-buffer ()
"Return a list of all known account names in the current buffer as strings.
@@ -108,9 +97,8 @@ Considers both accounts listed in postings and those declared with \"account\" d
(goto-char (point-min))
(let (results)
(while (re-search-forward ledger-account-name-or-directive-regex nil t)
- (setq results (cons (match-string-no-properties 2) results)))
- (ledger-accounts-deduplicate-sorted
- (sort results #'ledger-string-greaterp)))))
+ (setq results (cons (match-string-no-properties 1) results)))
+ (sort (delete-dups results) #'string-lessp))))
(defun ledger-accounts-list ()
"Return a list of all known account names as strings.
@@ -126,12 +114,12 @@ Looks in `ledger-accounts-file' if set, otherwise the current buffer."
(interactive)
(let ((account-tree (list t))
(account-elements nil)
- (prefix (or (car pcomplete-args) "")))
+ (prefix ""))
(save-excursion
(goto-char (point-min))
(dolist (account
- (cl-remove-if-not (lambda (c) (string-prefix-p prefix c pcomplete-ignore-case))
+ (cl-remove-if-not (lambda (c) (string-prefix-p prefix c))
(ledger-accounts-list)))
(let ((root account-tree))
(setq account-elements
@@ -223,37 +211,51 @@ Looks in `ledger-accounts-file' if set, otherwise the current buffer."
(defun ledger-complete-at-point ()
"Do appropriate completion for the thing at point."
- (interactive)
- (while (pcomplete-here
- (cond
- ((looking-back (concat "^" ledger-incomplete-date-regexp) nil)
- (ledger-complete-date (match-string 1) (match-string 2)))
- ((looking-back (concat "^" ledger-iso-date-regexp "="
- ledger-incomplete-date-regexp) nil)
- (ledger-complete-effective-date
- (match-string 2) (match-string 3) (match-string 4)
- (match-string 5) (match-string 6)))
- ((eq (save-excursion
- (ledger-thing-at-point)) 'transaction)
- (if (null current-prefix-arg)
- (delete
- (caar (ledger-parse-arguments))
- (ledger-payees-in-buffer)) ;; this completes against payee names
- (progn
- (let ((text (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position))))
- (delete-region (line-beginning-position)
- (line-end-position))
- (condition-case nil
- (ledger-add-transaction text t)
- (error nil)))
- (forward-line)
- (goto-char (line-end-position))
- (search-backward ";" (line-beginning-position) t)
- (skip-chars-backward " \t0123456789.,")
- (throw 'pcompleted t))))
- (t (ledger-accounts-tree))))))
+ (let ((end (point))
+ start collection
+ realign-after
+ delete-suffix)
+ (cond (;; Date
+ (looking-back (concat "^" ledger-incomplete-date-regexp) (line-beginning-position))
+ (setq collection (ledger-complete-date (match-string 1) (match-string 2))
+ start (match-beginning 0)
+ delete-suffix (save-match-data
+ (when (looking-at (rx (one-or-more (or digit (any ?/ ?-)))))
+ (length (match-string 0))))))
+ (;; Effective dates
+ (looking-back (concat "^" ledger-iso-date-regexp "=" ledger-incomplete-date-regexp)
+ (line-beginning-position))
+ (setq start (line-beginning-position))
+ (setq collection (ledger-complete-effective-date
+ (match-string 2) (match-string 3) (match-string 4)
+ (match-string 5) (match-string 6))))
+ (;; Payees
+ (eq (save-excursion (ledger-thing-at-point)) 'transaction)
+ (setq start (save-excursion (backward-word) (point)))
+ (setq collection #'ledger-payees-in-buffer))
+ ((looking-back (rx-to-string `(seq bol (one-or-more space) (group (zero-or-more (not space))))) (line-beginning-position))
+ (setq start (match-beginning 1)
+ delete-suffix (save-excursion
+ (when (search-forward-regexp (rx (or eol (repeat 2 space))) (line-end-position) t)
+ (- (match-beginning 0) end)))
+ realign-after t
+ collection (if ledger-complete-in-steps
+ #'ledger-accounts-tree
+ #'ledger-accounts-list))))
+ (when collection
+ (let ((prefix (buffer-substring-no-properties start end)))
+ (list start end
+ (if (functionp collection)
+ (completion-table-dynamic
+ (lambda (_)
+ (cl-remove-if (apply-partially 'string= prefix) (funcall collection))))
+ collection)
+ :exit-function (lambda (&rest _)
+ (when delete-suffix
+ (delete-char delete-suffix))
+ (when (and realign-after ledger-post-auto-align)
+ (ledger-post-align-postings (line-beginning-position) (line-end-position))))
+ 'ignore)))))
(defun ledger-trim-trailing-whitespace (str)
(replace-regexp-in-string "[ \t]*$" "" str))
@@ -294,57 +296,6 @@ Does not use ledger xact"
(if (re-search-backward "\\(\t\\| [ \t]\\)" nil t)
(goto-char (match-end 0))))))
-
-(defcustom ledger-complete-ignore-case t
- "Non-nil means that ledger-complete-at-point will be case-insensitive"
- :type 'boolean
- :group 'ledger)
-
-(defun ledger-pcomplete (&optional interactively)
- "Complete rip-off of pcomplete from pcomplete.el, only added
-ledger-magic-tab in the previous commands list so that
-ledger-magic-tab would cycle properly"
- (interactive "p")
- (let ((pcomplete-ignore-case ledger-complete-ignore-case))
- (if (and interactively
- pcomplete-cycle-completions
- pcomplete-current-completions
- (memq last-command '(ledger-magic-tab
- ledger-pcomplete
- pcomplete-expand-and-complete
- pcomplete-reverse)))
- (progn
- (delete-char (* -1 pcomplete-last-completion-length))
- (if (eq this-command 'pcomplete-reverse)
- (progn
- (push (car (last pcomplete-current-completions))
- pcomplete-current-completions)
- (setcdr (last pcomplete-current-completions 2) nil))
- (nconc pcomplete-current-completions
- (list (car pcomplete-current-completions)))
- (setq pcomplete-current-completions
- (cdr pcomplete-current-completions)))
- (pcomplete-insert-entry pcomplete-last-completion-stub
- (car pcomplete-current-completions)
- nil pcomplete-last-completion-raw))
- (setq pcomplete-current-completions nil
- pcomplete-last-completion-raw nil)
- (catch 'pcompleted
- (let* (pcomplete-stub
- pcomplete-seen pcomplete-norm-func
- pcomplete-args pcomplete-last pcomplete-index
- pcomplete-autolist
- (completions (pcomplete-completions))
- (result (pcomplete-do-complete pcomplete-stub completions))
- (pcomplete-termination-string ""))
- (and result
- (not (eq (car result) 'listed))
- (cdr result)
- (pcomplete-insert-entry pcomplete-stub (cdr result)
- (memq (car result)
- '(sole shortest))
- pcomplete-last-completion-raw)))))))
-
(provide 'ledger-complete)
;;; ledger-complete.el ends here
diff --git a/ledger-context.el b/ledger-context.el
index ac76708..0a225c5 100644
--- a/ledger-context.el
+++ b/ledger-context.el
@@ -39,7 +39,7 @@
(defconst ledger-balance-assertion-string ledger-balance-assertion-regexp)
(defconst ledger-comment-string "[ \t]*;[ \t]*\\(.*?\\)")
(defconst ledger-nil-string "\\([ \t]+\\)")
-(defconst ledger-date-string "^\\([0-9]\\{4\\}[/-][01]?[0-9][/-][0123]?[0-9]\\)")
+(defconst ledger-date-string "^\\([0-9]\\{4\\}[/-][01]?[0-9][/-][0123]?[0-9]\\)\\(?:=[0-9]\\{4\\}[/-][01]?[0-9][/-][0123]?[0-9]\\)?")
(defconst ledger-code-string "\\((.*)\\)?")
(defconst ledger-payee-string "\\(.*[^[:space:]]\\)")
diff --git a/ledger-exec.el b/ledger-exec.el
index f83e3cd..84e52b8 100644
--- a/ledger-exec.el
+++ b/ledger-exec.el
@@ -25,6 +25,8 @@
;;; Code:
+(declare-function ledger-master-file "ledger-report" ())
+
(defconst ledger-version-needed "3.0.0"
"The version of ledger executable needed for interactive features.")
@@ -43,6 +45,7 @@
(defcustom ledger-binary-path "ledger"
"Path to the ledger executable."
:type 'file
+ :risky t
:group 'ledger-exec)
(defun ledger-exec-handle-error (ledger-errfile)
@@ -75,18 +78,20 @@ otherwise the error output is displayed and an error is raised."
(outbuf (or output-buffer
(generate-new-buffer " *ledger-tmp*")))
(errfile (make-temp-file "ledger-errors")))
- (with-current-buffer buf
- (let ((exit-code
- (let ((coding-system-for-write 'utf-8)
- (coding-system-for-read 'utf-8))
- (apply #'call-process-region
- (append (list (point-min) (point-max)
- ledger-binary-path nil (list outbuf errfile) nil "-f" "-")
- args)))))
- (if (ledger-exec-success-p exit-code outbuf)
- outbuf
- (display-buffer (ledger-exec-handle-error errfile))
- (error "Ledger execution failed")))))))
+ (unwind-protect
+ (with-current-buffer buf
+ (let ((exit-code
+ (let ((coding-system-for-write 'utf-8)
+ (coding-system-for-read 'utf-8))
+ (apply #'call-process-region
+ (append (list (point-min) (point-max)
+ ledger-binary-path nil (list outbuf errfile) nil "-f" "-")
+ args)))))
+ (if (ledger-exec-success-p exit-code outbuf)
+ outbuf
+ (display-buffer (ledger-exec-handle-error errfile))
+ (error "Ledger execution failed"))))
+ (delete-file errfile)))))
(defun ledger-version-greater-p (needed)
"Verify the ledger binary is usable for `ledger-mode' (version greater than NEEDED)."
diff --git a/ledger-flymake.el b/ledger-flymake.el
index b164832..182efd7 100644
--- a/ledger-flymake.el
+++ b/ledger-flymake.el
@@ -29,6 +29,10 @@
(require 'flymake)
(require 'ledger-exec) ; for `ledger-binary-path'
+;; To silence byte compiler warnings in Emacs 25 and older:
+(declare-function flymake-diag-region "flymake" (buffer line &optional col))
+(declare-function flymake-make-diagnostic "flymake" (buffer beg end type text &optional data overlay-properties))
+
(defvar-local ledger--flymake-proc nil)
(defcustom ledger-flymake-be-pedantic nil
@@ -71,10 +75,12 @@ Flymake calls this with REPORT-FN as needed."
(make-process
:name "ledger-flymake" :noquery t :connection-type 'pipe
:buffer (generate-new-buffer " *ledger-flymake*")
- :command `(,ledger-binary-path "-f" ,file
- ,(when ledger-flymake-be-pedantic "--pedantic")
- ,(when ledger-flymake-be-explicit "--explicit")
- "balance")
+ :command (cl-remove
+ nil
+ `(,ledger-binary-path "-f" ,file
+ ,(when ledger-flymake-be-pedantic "--pedantic")
+ ,(when ledger-flymake-be-explicit "--explicit")
+ "balance"))
:sentinel
(lambda (proc _event)
;; Check that the process has indeed exited, as it might
diff --git a/ledger-init.el b/ledger-init.el
index a7c412a..f5d4c3f 100644
--- a/ledger-init.el
+++ b/ledger-init.el
@@ -37,9 +37,12 @@
Adding the dotted pair (\"decimal-comma\" . t) will tell ledger
to treat commas as decimal separator.")
-(defvar ledger-default-date-format "%Y/%m/%d"
+(defcustom ledger-default-date-format "%Y/%m/%d"
"The date format that ledger uses throughout.
-Set this to `ledger-iso-date-format' if you prefer ISO 8601 dates.")
+Set this to the value of `ledger-iso-date-format' if you prefer
+ISO 8601 dates."
+ :type 'string
+ :group 'ledger)
(defconst ledger-iso-date-format "%Y-%m-%d"
"The format for ISO 8601 dates.")
diff --git a/ledger-mode.el b/ledger-mode.el
index dc92f73..bdd1b5e 100644
--- a/ledger-mode.el
+++ b/ledger-mode.el
@@ -149,17 +149,6 @@ And calculate the target-delta of the account being reconciled."
(when balance
(message balance))))
-(defun ledger-magic-tab (&optional interactively)
- "Decide what to with with <TAB>, INTERACTIVELY.
-Can indent, complete or align depending on context."
- (interactive "p")
- (if (= (point) (line-beginning-position))
- (indent-to ledger-post-account-alignment-column)
- (if (and (> (point) 1)
- (looking-back "\\([^ \t]\\)" 1))
- (ledger-pcomplete interactively)
- (ledger-post-align-postings (line-beginning-position) (line-end-position)))))
-
(defvar ledger-mode-abbrev-table)
(defvar ledger-date-string-today (ledger-format-date))
@@ -264,9 +253,7 @@ With a prefix argument, remove the effective date."
(define-key map [(control ?c) (control ?l)] #'ledger-display-ledger-stats)
(define-key map [(control ?c) (control ?q)] #'ledger-post-align-xact)
- (define-key map [tab] #'ledger-magic-tab)
(define-key map [(control tab)] #'ledger-post-align-xact)
- (define-key map [(control ?i)] #'ledger-magic-tab)
(define-key map [(control ?c) tab] #'ledger-fully-complete-xact)
(define-key map [(control ?c) (control ?i)] #'ledger-fully-complete-xact)
@@ -330,17 +317,14 @@ With a prefix argument, remove the effective date."
(setq font-lock-defaults
'(ledger-font-lock-keywords t nil nil nil))
(add-hook 'font-lock-extend-region-functions 'ledger-fontify-extend-region)
-
- (setq-local pcomplete-parse-arguments-function 'ledger-parse-arguments)
- (setq-local pcomplete-command-completion-function 'ledger-complete-at-point)
- (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point nil t)
+ (add-hook 'completion-at-point-functions #'ledger-complete-at-point nil t)
(add-hook 'after-save-hook 'ledger-report-redo nil t)
(add-hook 'post-command-hook 'ledger-highlight-xact-under-point nil t)
(ledger-init-load-init-file)
(setq-local comment-start ";")
-
+ (setq-local indent-line-function #'ledger-indent-line)
(setq-local indent-region-function 'ledger-post-align-postings))
;;;###autoload
diff --git a/ledger-navigate.el b/ledger-navigate.el
index eb5765c..811662c 100644
--- a/ledger-navigate.el
+++ b/ledger-navigate.el
@@ -97,37 +97,42 @@ Requires empty line separating xacts."
(list (ledger-navigate-beginning-of-xact)
(ledger-navigate-end-of-xact))))
+(defun ledger-navigate-skip-lines-backwards (re)
+ "Move backwards if necessary until RE does not match at the beginning of the line."
+ (beginning-of-line)
+ (while (and (looking-at-p re)
+ (zerop (forward-line -1)))))
+
+(defun ledger-navigate-skip-lines-forwards (re)
+ "Move forwards if necessary until RE does not match at the beginning of the line."
+ (beginning-of-line)
+ (while (and (looking-at-p re)
+ (zerop (forward-line 1)))))
+
(defun ledger-navigate-find-directive-extents (pos)
"Return the extents of the directive at POS."
(goto-char pos)
- (let ((begin (progn (beginning-of-line)
- (while (looking-at "[ \t]\\|end[[:blank:]]+\\(?:comment\\|test\\)")
- (forward-line -1))
+ (let ((begin (progn (ledger-navigate-skip-lines-backwards "[ \t]\\|end[[:blank:]]+\\(?:comment\\|test\\)")
(point)))
(end (progn (forward-line 1)
- (while (looking-at "[ \t]")
- (forward-line 1))
- (point))))
+ (ledger-navigate-skip-lines-forwards "[ \t]")
+ (point)))
+ (comment-re " *;"))
;; handle block comments here
(goto-char begin)
(cond
- ((looking-at " *;")
+ ((looking-at comment-re)
(progn
- (while (and (looking-at " *;")
- (> (point) (point-min)))
- (forward-line -1))
+ (ledger-navigate-skip-lines-backwards comment-re)
;; We are either at the beginning of the buffer, or we found
;; a line outside the comment, or both. If we are outside
;; the comment then we need to move forward a line.
- (unless (looking-at " *;")
+ (unless (looking-at comment-re)
(forward-line 1)
(beginning-of-line))
(setq begin (point))
(goto-char pos)
- (beginning-of-line)
- (while (and (looking-at " *;")
- (< (point) (point-max)))
- (forward-line 1))
+ (ledger-navigate-skip-lines-forwards comment-re)
(setq end (point))))
((looking-at "\\(?:comment\\|test\\)\\>")
(setq end (or (save-match-data
@@ -142,20 +147,17 @@ Requires empty line separating xacts."
(let ((begin (progn (beginning-of-line)
(point)))
(end (progn (end-of-line)
- (point))))
+ (point)))
+ (comment-re " *;"))
;; handle block comments here
(beginning-of-line)
- (if (looking-at " *;")
+ (if (looking-at comment-re)
(progn
- (while (and (looking-at " *;")
- (> (point) (point-min)))
- (forward-line -1))
+ (ledger-navigate-skip-lines-backwards comment-re)
(setq begin (point))
(goto-char pos)
(beginning-of-line)
- (while (and (looking-at " *;")
- (< (point) (point-max)))
- (forward-line 1))
+ (ledger-navigate-skip-lines-forwards comment-re)
(setq end (point))))
(list begin end)))
@@ -166,12 +168,31 @@ Requires empty line separating xacts."
(save-excursion
(goto-char pos)
(beginning-of-line)
- (while (looking-at "[ \t]\\|end[[:blank:]]+\\(?:comment\\|test\\)\\_>")
- (forward-line -1))
+ (ledger-navigate-skip-lines-backwards "[ \t]\\|end[[:blank:]]+\\(?:comment\\|test\\)\\_>")
(if (looking-at "[=~0-9\\[]")
(ledger-navigate-find-xact-extents pos)
(ledger-navigate-find-directive-extents pos))))
+(defun ledger-navigate-next-uncleared ()
+ "Move point to the next uncleared transaction."
+ (interactive)
+ (when (looking-at ledger-payee-uncleared-regex)
+ (forward-line))
+ (if (re-search-forward ledger-payee-uncleared-regex nil t)
+ (progn (beginning-of-line)
+ (point))
+ (user-error "No next uncleared transactions")))
+
+(defun ledger-navigate-previous-uncleared ()
+ "Move point to the previous uncleared transaction."
+ (interactive)
+ (when (equal (car (ledger-context-at-point)) 'acct-transaction)
+ (ledger-navigate-beginning-of-xact))
+ (if (re-search-backward ledger-payee-uncleared-regex nil t)
+ (progn (beginning-of-line)
+ (point))
+ (user-error "No previous uncleared transactions")))
+
(provide 'ledger-navigate)
diff --git a/ledger-occur.el b/ledger-occur.el
index 6741b72..bfd006e 100644
--- a/ledger-occur.el
+++ b/ledger-occur.el
@@ -106,7 +106,8 @@ currently active."
(defun ledger-occur-make-visible-overlay (beg end)
(let ((ovl (make-overlay beg end (current-buffer))))
(overlay-put ovl ledger-occur-overlay-property-name t)
- (overlay-put ovl 'font-lock-face 'ledger-occur-xact-face)))
+ (when ledger-occur-use-face-shown
+ (overlay-put ovl 'font-lock-face 'ledger-occur-xact-face))))
(defun ledger-occur-make-invisible-overlay (beg end)
(let ((ovl (make-overlay beg end (current-buffer))))
diff --git a/ledger-post.el b/ledger-post.el
index 19b8ae5..982863d 100644
--- a/ledger-post.el
+++ b/ledger-post.el
@@ -43,7 +43,7 @@
:group 'ledger-post)
(defcustom ledger-post-amount-alignment-at :end
- "Position at which the amount is ailgned.
+ "Position at which the amount is aligned.
Can be :end to align on the last number of the amount (can be
followed by unaligned commodity) or :decimal to align at the
@@ -52,6 +52,12 @@ decimal separator."
(const :tag "align at the decimal separator" :decimal))
:group 'ledger-post)
+(defcustom ledger-post-auto-align t
+ "When non-nil, realign post amounts when indenting or completing."
+ :type 'boolean
+ :group 'ledger-post
+ :safe 'booleanp)
+
(defun ledger-next-amount (&optional 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 and leave
@@ -120,6 +126,20 @@ Looks only as far as END, if supplied, otherwise `point-max'."
(delete-char amt-adjust)))))))
(forward-line 1))))))
+(defun ledger-indent-line ()
+ "Indent the current line."
+ ;; Ensure indent if the previous line was indented
+ (let ((indent-level (save-excursion (if (progn (when (zerop (forward-line -1))
+ (memq (ledger-thing-at-point) '(transaction posting))))
+ ledger-post-account-alignment-column
+ 0))))
+ (unless (= (current-indentation) indent-level)
+ (back-to-indentation)
+ (delete-horizontal-space t)
+ (indent-to indent-level)))
+ (when ledger-post-auto-align
+ (ledger-post-align-postings (line-beginning-position) (line-end-position))))
+
(defun ledger-post-align-dwim ()
"Align all the posting of the current xact or the current region.
diff --git a/ledger-reconcile.el b/ledger-reconcile.el
index fc5779a..4522b21 100644
--- a/ledger-reconcile.el
+++ b/ledger-reconcile.el
@@ -181,7 +181,7 @@ Possible values are '(date)', '(amount)', '(payee)' or '(0)' for no sorting, i.e
;; split arguments like the shell does, so you need to
;; specify the individual fields in the command line.
(ledger-exec-ledger buffer (current-buffer)
- "balance" "--limit" "cleared or pending" "--empty" "--collapse"
+ "balance" "--real" "--limit" "cleared or pending" "--empty" "--collapse"
"--format" "%(scrub(display_total))" account)
(ledger-split-commodity-string
(buffer-substring-no-properties (point-min) (point-max)))))
diff --git a/ledger-regex.el b/ledger-regex.el
index 9d858c8..8ac3002 100644
--- a/ledger-regex.el
+++ b/ledger-regex.el
@@ -22,6 +22,8 @@
(require 'rx)
(require 'cl-lib)
+(defvar ledger-iso-date-regex)
+
(defconst ledger-amount-regex
(concat "\\( \\|\t\\| \t\\)[ \t]*-?"
"\\([A-Z$€£₹_(]+ *\\)?"
@@ -71,28 +73,28 @@
(defconst ledger-init-string-regex
"^--.+?\\($\\|[ ]\\)")
+(defconst ledger-account-name-regex
+ "\\(?1:[^][(); \t\r\n]+\\(?: [^][(); \t\r\n]+\\)*\\)")
+
(defconst ledger-account-directive-regex
- "^account [ \t]*\\(?2:[^;]+?\\)\\(?3:[ \t]*\\)\\(;.*\\)?$")
+ (concat "^account[ \t]+" ledger-account-name-regex))
-(defconst ledger-account-any-status-no-trailing-spaces-regex
- "^[ \t]+\\(?1:[*!]\\s-+\\)?[[(]?\\(?2:[^; ].+?\\)[])]?")
+(defconst ledger-account-name-maybe-virtual-regex
+ (concat "[[(]?" ledger-account-name-regex "[])]?"))
(defconst ledger-account-any-status-regex
- (format "%s%s"
- ledger-account-any-status-no-trailing-spaces-regex
- "\\(?3:\t\\| [ \t]\\|$\\)"))
+ (concat "^[ \t]+\\(?:[!*][ \t]*\\)?" ledger-account-name-maybe-virtual-regex))
+;; This would incorrectly match "account (foo)", but writing the regexp this way
+;; allows us to have just one match result
(defconst ledger-account-name-or-directive-regex
- (format "\\(?:%s\\|%s\\(?3:\t\\| [ \t]\\)\\)"
- ledger-account-directive-regex
- ledger-account-any-status-no-trailing-spaces-regex))
+ (format "\\(?:%s\\|%s\\)" ledger-account-any-status-regex ledger-account-directive-regex))
(defconst ledger-account-pending-regex
- "\\(^[ \t]+\\)\\(!\\s-*[^ ].*?\\)\\( \\|\t\\|$\\)")
+ (concat "\\(^[ \t]+\\)!" ledger-account-name-maybe-virtual-regex))
(defconst ledger-account-cleared-regex
- "\\(^[ \t]+\\)\\(*\\s-*[^ ].*?\\)\\( \\|\t\\|$\\)")
-
+ (concat "\\(^[ \t]+\\)*" ledger-account-name-maybe-virtual-regex))
(defmacro ledger-define-regexp (name regex docs &rest args)
"Simplify the creation of a Ledger regex and helper functions."
diff --git a/ledger-report.el b/ledger-report.el
index c0adaba..25f22d9 100644
--- a/ledger-report.el
+++ b/ledger-report.el
@@ -150,6 +150,9 @@ when running reports?"
(defvar ledger-report-is-reversed nil)
(defvar ledger-report-cursor-line-number nil)
+(defvar-local ledger-master-file nil
+ "The master file for the current buffer.
+See documentation for the function `ledger-master-file'")
(defun ledger-report-reverse-report ()
"Reverse the order of the report."
@@ -188,6 +191,7 @@ when running reports?"
#'ledger-report-save)
(define-key map [(control ?c) (control ?l) (control ?e)]
#'ledger-report-edit-report)
+ (define-key map [(control ?c) (control ?o) (control ?r)] #'ledger-report)
(define-key map (kbd "M-p") #'ledger-report-previous-month)
(define-key map (kbd "M-n") #'ledger-report-next-month)
(define-key map (kbd "$") #'ledger-report-toggle-default-commodity)
@@ -265,13 +269,13 @@ used to generate the buffer, navigating the buffer, etc."
(let ((rname (ledger-report-read-name))
(edit (not (null current-prefix-arg))))
(list rname edit))))
- (let ((buf (find-file-noselect (ledger-master-file)))
- (rbuf (get-buffer ledger-report-buffer-name))
- (wcfg (current-window-configuration)))
- (if rbuf
- (kill-buffer rbuf))
+ (let* ((file (ledger-master-file))
+ (buf (find-file-noselect file))
+ (wcfg (current-window-configuration)))
(with-current-buffer
(pop-to-buffer (get-buffer-create ledger-report-buffer-name))
+ (let ((inhibit-read-only t))
+ (erase-buffer))
(ledger-report-mode)
(set (make-local-variable 'ledger-report-saved) nil)
(set (make-local-variable 'ledger-buf) buf)
@@ -279,6 +283,7 @@ used to generate the buffer, navigating the buffer, etc."
(set (make-local-variable 'ledger-original-window-cfg) wcfg)
(set (make-local-variable 'ledger-report-is-reversed) nil)
(set (make-local-variable 'ledger-report-current-month) nil)
+ (set 'ledger-master-file file)
(ledger-do-report (ledger-report-cmd report-name edit))
(ledger-report-maybe-shrink-window)
(set-buffer-modified-p nil)
@@ -329,10 +334,6 @@ used to generate the buffer, navigating the buffer, etc."
;; General helper functions
-(defvar-local ledger-master-file nil
- "The master file for the current buffer.
-See documentation for the function `ledger-master-file'")
-
(defun ledger-master-file ()
"Return the master file for a ledger file.
diff --git a/ledger-xact.el b/ledger-xact.el
index 6f61bba..f8fb216 100644
--- a/ledger-xact.el
+++ b/ledger-xact.el
@@ -30,7 +30,8 @@
(require 'ledger-navigate)
(require 'ledger-exec)
(require 'ledger-post)
-(declare-function ledger-read-date "ledger-mode")
+(declare-function ledger-read-date "ledger-mode" (prompt))
+(declare-function ledger-format-date "ledger-init" (&optional date))
;; TODO: This file depends on code in ledger-mode.el, which depends on this.
@@ -62,16 +63,30 @@
(move-overlay ledger-xact-highlight-overlay b (+ 1 e))
(move-overlay ledger-xact-highlight-overlay 1 1))))))
-(defun ledger-xact-payee ()
- "Return the payee of the transaction containing point or nil."
+(defun ledger-xact-context ()
+ "Return the context of the transaction containing point or nil."
(let ((i 0))
(while (eq (ledger-context-line-type (ledger-context-other-line i)) 'acct-transaction)
(setq i (- i 1)))
(let ((context-info (ledger-context-other-line i)))
(if (eq (ledger-context-line-type context-info) 'xact)
- (ledger-context-field-value context-info 'payee)
+ context-info
nil))))
+(defun ledger-xact-payee ()
+ "Return the payee of the transaction containing point or nil."
+ (let ((xact-context (ledger-xact-context)))
+ (if xact-context
+ (ledger-context-field-value xact-context 'payee)
+ nil)))
+
+(defun ledger-xact-date ()
+ "Return the date of the transaction containing point or nil."
+ (let ((xact-context (ledger-xact-context)))
+ (if xact-context
+ (ledger-context-field-value xact-context 'date)
+ nil)))
+
(defun ledger-time-less-p (t1 t2)
"Say whether time value T1 is less than time value T2."
;; TODO: assert listp, or support when both are strings
@@ -120,6 +135,9 @@ MOMENT is an encoded date"
mark desc)))))
(forward-line))))
+(defvar ledger-copy-transaction-insert-blank-line-after nil
+ "Non-nil means insert blank line after a transaction inserted with ‘ledger-copy-transaction-at-point’.")
+
(defun ledger-copy-transaction-at-point (date)
"Ask for a new DATE and copy the transaction under point to that date. Leave point on the first amount."
(interactive (list
@@ -128,7 +146,10 @@ MOMENT is an encoded date"
(transaction (buffer-substring-no-properties (car extents) (cadr extents)))
(encoded-date (ledger-parse-iso-date date)))
(ledger-xact-find-slot encoded-date)
- (insert transaction "\n")
+ (insert transaction
+ (if ledger-copy-transaction-insert-blank-line-after
+ "\n\n"
+ "\n"))
(beginning-of-line -1)
(ledger-navigate-beginning-of-xact)
(re-search-forward ledger-iso-date-regexp)
@@ -141,19 +162,23 @@ MOMENT is an encoded date"
"Delete the transaction surrounging POS."
(interactive "d")
(let ((bounds (ledger-navigate-find-xact-extents pos)))
- (delete-region (car bounds) (cadr bounds))))
+ (delete-region (car bounds) (cadr bounds)))
+ (delete-blank-lines))
(defvar ledger-add-transaction-last-date nil
"Last date entered using `ledger-read-transaction'.")
(defun ledger-read-transaction ()
"Read the text of a transaction, which is at least the current date."
- (let ((reference-date (or ledger-add-transaction-last-date (current-time))))
- (read-string
- "Transaction: "
- ;; Pre-fill year and month, but not day: this assumes DD is the last format arg.
- (ledger-format-date reference-date)
- 'ledger-minibuffer-history)))
+ (let* ((reference-date (or ledger-add-transaction-last-date (current-time)))
+ (full-date-string (ledger-format-date reference-date))
+ ;; Pre-fill year and month, but not day: this assumes DD is the last format arg.
+ (initial-string (replace-regexp-in-string "[0-9]+$" "" full-date-string))
+ (entered-string (read-string "Transaction: "
+ initial-string 'ledger-minibuffer-history)))
+ (if (string= initial-string entered-string)
+ full-date-string
+ entered-string)))
(defun ledger-parse-iso-date (date)
"Try to parse DATE using `ledger-iso-date-regexp' and return a time value or nil."
@@ -172,14 +197,17 @@ correct chronological place in the buffer."
(let* ((args (with-temp-buffer
(insert transaction-text)
(eshell-parse-arguments (point-min) (point-max))))
- (ledger-buf (current-buffer)))
+ (ledger-buf (current-buffer))
+ (separator "\n"))
(unless insert-at-point
(let* ((date (car args))
(parsed-date (ledger-parse-iso-date date)))
(setq ledger-add-transaction-last-date parsed-date)
(push-mark)
;; TODO: what about when it can't be parsed?
- (ledger-xact-find-slot (or parsed-date date))))
+ (ledger-xact-find-slot (or parsed-date date))
+ (when (looking-at "\n*\\'")
+ (setq separator ""))))
(if (> (length args) 1)
(save-excursion
(insert
@@ -189,10 +217,10 @@ correct chronological place in the buffer."
(goto-char (point-min))
(ledger-post-align-postings (point-min) (point-max))
(buffer-string))
- "\n"))
+ separator))
(progn
- (insert (car args) " \n\n")
- (end-of-line -1)))))
+ (insert (car args) " ")
+ (save-excursion (insert "\n" separator))))))
(provide 'ledger-xact)
diff --git a/test/Makefile b/test/Makefile
index 6d15ff0..7d54410 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
EMACS ?= emacs
EMACS_FLAGS = --quick --directory . --directory ..
-EMACS_BATCH = $(EMACS) --batch $(EMACS_FLAGS)
-EMACS_INTERACTIVE = $(EMACS) $(EMACS_FLAGS)
+EMACS_BATCH = "$(EMACS)" --batch $(EMACS_FLAGS)
+EMACS_INTERACTIVE = "$(EMACS)" $(EMACS_FLAGS)
EL := $(wildcard *.el)
ELC := $(patsubst %.el,%.elc,$(EL))
diff --git a/test/complete-test.el b/test/complete-test.el
index a8028be..d5082ce 100644
--- a/test/complete-test.el
+++ b/test/complete-test.el
@@ -35,25 +35,26 @@ http://bugs.ledger-cli.org/show_bug.cgi?id=969
http://bugs.ledger-cli.org/show_bug.cgi?id=582"
:tags '(complete regress)
- (ledger-tests-with-temp-file
- "2013/05/19 Retrait
+ (let ((ledger-complete-in-steps t))
+ (ledger-tests-with-temp-file
+ "2013/05/19 Retrait
Dépense:Alimentation:Épicerie 35 € ; Marché
Dépense:Alimentation:Épicerie 8,1 € ; Arum café
Dépense:Liquide
* Passif:Crédit:BanqueAccord -60,00 €"
- (forward-line 1)
- (move-end-of-line 1)
- (newline)
- (insert " Dé")
- (call-interactively #'ledger-magic-tab)
- (should
- (equal (buffer-string)
- "2013/05/19 Retrait
+ (forward-line 1)
+ (move-end-of-line 1)
+ (newline)
+ (insert " Dé")
+ (call-interactively #'completion-at-point)
+ (should
+ (equal (buffer-string)
+ "2013/05/19 Retrait
Dépense:Alimentation:Épicerie 35 € ; Marché
Dépense:
Dépense:Alimentation:Épicerie 8,1 € ; Arum café
Dépense:Liquide
- * Passif:Crédit:BanqueAccord -60,00 €"))))
+ * Passif:Crédit:BanqueAccord -60,00 €")))))
(ert-deftest ledger-complete/test-002 ()
@@ -62,17 +63,17 @@ http://bugs.ledger-cli.org/show_bug.cgi?id=252"
:tags '(complete regress)
(ledger-tests-with-temp-file
- "2010/04/08 payee
+ "2010/04/08 payee
account1 1 €
account2
"
- (goto-char (point-max))
- (newline)
- (insert "2016/09/01 payee")
- (ledger-fully-complete-xact)
- (should
- (equal (buffer-string)
- "2010/04/08 payee
+ (goto-char (point-max))
+ (newline)
+ (insert "2016/09/01 payee")
+ (ledger-fully-complete-xact)
+ (should
+ (equal (buffer-string)
+ "2010/04/08 payee
account1 1 €
account2
@@ -81,14 +82,54 @@ http://bugs.ledger-cli.org/show_bug.cgi?id=252"
account2
"))))
+(ert-deftest ledger-complete/test-complete-account-without-amount ()
+ "https://github.com/ledger/ledger-mode/issues/141"
+ :tags '(complete regress)
+ (ledger-tests-with-temp-file
+ "2010/04/08 payee
+ blah 1 €
+ bloop
+
+2010/04/09 payee
+ blo"
+ (goto-char (point-max))
+ (call-interactively 'completion-at-point)
+ (should
+ (equal (buffer-string)
+ "2010/04/08 payee
+ blah 1 €
+ bloop
+
+2010/04/09 payee
+ bloop"))))
+
+(ert-deftest ledger-complete/test-complete-single-payee ()
+ "https://github.com/ledger/ledger-mode/issues/181"
+ :tags '(complete regress)
+ (ledger-tests-with-temp-file
+ "2019/06/28 Foobar
+ Expenses:Baz 11.99 CAD
+ Assets:Cash
+
+2019/06/20 Foo"
+ (goto-char (point-max))
+ (call-interactively 'completion-at-point)
+ (should
+ (equal (buffer-string)
+ "2019/06/28 Foobar
+ Expenses:Baz 11.99 CAD
+ Assets:Cash
+
+2019/06/20 Foobar"))))
+
(ert-deftest ledger-complete/test-find-accounts-in-buffer ()
(let ((ledger "*** Expenses
account Expenses:Accomodation
account Assets:Cash ; some comment
account Assets:Current
- alias 1187465S022
+; alias 1187465S022 -- Ideally this line could be uncommented
commodity EUR
- format 1,000.00 EUR
+; format 1,000.00 EUR -- Ideally this line could be uncommented
tag ofxid
2018/05/07 * Company
Assets:Current -38.33 EUR
@@ -103,15 +144,25 @@ tag ofxid
(insert ledger)
(should (equal
(ledger-accounts-list-in-buffer)
- (list ; I don't know why accounts are sorted in reverse order
- "Something"
- "Expenses:Utilities:Insurance"
- "Expenses:Accomodation"
- "Dimensions:Foo"
- "Dimensions:Equity"
+ (list
+ "Assets:Cash"
"Assets:Current"
- "Assets:Cash"))))))
+ "Dimensions:Equity"
+ "Dimensions:Foo"
+ "Expenses:Accomodation"
+ "Expenses:Utilities:Insurance"
+ "Something"))))))
+(ert-deftest ledger-complete/test-find-accounts-with-spaces-in-buffer ()
+ (let ((ledger "*** Expenses
+account Expenses:The Bakery
+"))
+ (with-temp-buffer
+ (insert ledger)
+ (should (equal
+ (ledger-accounts-list-in-buffer)
+ (list
+ "Expenses:The Bakery"))))))
(provide 'complete-test)
diff --git a/test/mode-test.el b/test/mode-test.el
index 1bfefdd..0135243 100644
--- a/test/mode-test.el
+++ b/test/mode-test.el
@@ -61,27 +61,19 @@
"Regress test for Bug 256
http://bugs.ledger-cli.org/show_bug.cgi?id=256"
:tags '(mode regress)
-
- (ledger-tests-with-temp-file
- ""
-
- (comment-dwim nil)
- (should (equal (buffer-string) "; ")) ; Expected: no space before ';'
- ))
-
+ (ledger-tests-with-temp-file ""
+ (comment-dwim nil)
+ (should (string-match (rx buffer-start ";" (0+ whitespace))
+ ;; Expected: no space before ';'
+ (buffer-string)))))
(ert-deftest ledger-mode/test-003 ()
"Baseline test for comment-start"
:tags '(mode baseline)
-
- (ledger-tests-with-temp-file
- ""
-
- (setq comment-start "#")
- (comment-dwim nil)
- (should (equal (buffer-string) "# "))
- ))
-
+ (ledger-tests-with-temp-file ""
+ (setq comment-start "#")
+ (comment-dwim nil)
+ (should (string-match (rx buffer-start "#" (0+ whitespace)) (buffer-string)))))
(provide 'mode-test)
diff --git a/test/navigate-test.el b/test/navigate-test.el
index 84656b1..503dbc8 100644
--- a/test/navigate-test.el
+++ b/test/navigate-test.el
@@ -43,6 +43,34 @@ http://bugs.ledger-cli.org/show_bug.cgi?id=441"
(ledger-navigate-prev-xact-or-directive)
(should (eq 104 (point)))))
+(ert-deftest ledger-navigate-uncleared ()
+ :tags '(navigate)
+ (with-temp-buffer
+ (insert
+ "2011/01/27 Book Store
+ Expenses:Books $20.00
+ Liabilities:MasterCard
+
+2011/04/25 * Tom's Used Cars
+ Expenses:Auto $ 5,500.00
+ Assets:Checking
+
+2011/04/27 Bookstore
+ Expenses:Books $20.00
+ Assets:Checking
+
+2011/12/01 * Sale
+ Assets:Checking $ 30.00
+ Income:Sales")
+ (ledger-mode)
+ (goto-char (point-min))
+ (ledger-navigate-next-uncleared)
+ (should (looking-at-p (regexp-quote "2011/04/27 Bookstore")))
+ (should-error (ledger-navigate-next-uncleared))
+ (ledger-navigate-previous-uncleared)
+ (should (bobp))
+ ))
+
(provide 'navigate-test)
diff --git a/test/reconcile-test.el b/test/reconcile-test.el
index 4c7c481..289ca16 100644
--- a/test/reconcile-test.el
+++ b/test/reconcile-test.el
@@ -716,7 +716,7 @@ http://bugs.ledger-cli.org/show_bug.cgi?id=262"
(should ;; Expected: this must be ledger buffer
(equal (buffer-name) ; current buffer name
(buffer-name ledger-buffer)))
- (should (= 1323 (point)))))) ; expected on "Book Store" xact
+ (should (= 1321 (point)))))) ; expected on "Book Store" xact
(ert-deftest ledger-reconcile/test-028 ()
diff --git a/test/test-helper.el b/test/test-helper.el
index f26b4e2..66fb09e 100644
--- a/test/test-helper.el
+++ b/test/test-helper.el
@@ -126,7 +126,8 @@ always located at the beginning of buffer."
(goto-char (point-min))
,@body)
(and ledger-buffer (kill-buffer ledger-buffer))
- (ledger-tests-reset-custom-values 'ledger))))
+ (ledger-tests-reset-custom-values 'ledger)
+ (delete-file temp-file))))
(defun ledger-test-visible-buffer-string ()
@@ -166,7 +167,7 @@ The two arguments START and END are character positions."
(defun ledger-test-face-groups (fontified)
- "Group a fontified string by face.
+ "Group a FONTIFIED string by face.
Return a list of substrings each followed by its face."
(cl-loop for start = 0 then end
while start
diff --git a/tools/travis-install-ledger.sh b/tools/travis-install-ledger.sh
deleted file mode 100755
index e30ba3b..0000000
--- a/tools/travis-install-ledger.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-
-set -eu -o pipefail
-set -o xtrace
-
-BRANCH=$1
-LAST_BUILD_FILE=travis-last-build
-
-if [ "${TRAVIS_OS_NAME}" = "linux" ]; then
- if [ "${BRANCH}" = "apt-get" ]; then
- sudo apt-get update -qq
- sudo apt-get install -qq ledger
- else
- sudo apt-get install -qq git
- sudo apt-get install -qq libboost-all-dev # ledger needs Boost's runtime libraries
- sudo apt-get install -qq libgmp-dev libmpfr-dev libedit-dev
-
- if [ ! -d "ledger-$BRANCH/.git" ]; then
- git clone --depth 1 -b "$BRANCH" "https://github.com/ledger/ledger/" "ledger-$BRANCH"
- fi
-
- cd "ledger-$BRANCH"
-
- git fetch origin
- git reset --hard "origin/$BRANCH"
-
- REV="$(git rev-parse "$BRANCH")"
-
- if [ "$(cat "$LAST_BUILD_FILE" 2> /dev/null)" = "$REV" ]; then
- echo "Build is up to date"
- else
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo apt-get update -qq
- sudo apt-get install -qq gcc-4.8 g++-4.8
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 90
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 90
-
- cmake .
- make -j2
- echo "$REV" > "$LAST_BUILD_FILE"
- fi
- fi
-fi
-
-if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
- brew update
- brew install ledger
-fi