Context-aware pcomplete rules.

Provide completions based on information retrieved with 'ledger-context-at-point'.
To support step-by-step completion of transactions some more patterns were added
to 'ledger-line-config'. The actual completion rules mostly reuse some of the
convenient input commands that are buried in ledger-mode. Using the standard
pcomplete termination string (" ") to allow a "context switch" at the end of each
completion step.
This commit is contained in:
4ourbit 2013-12-31 02:12:52 +01:00
parent c00e4eb8c6
commit 383f17f114
3 changed files with 76 additions and 34 deletions

View file

@ -145,9 +145,38 @@ Return list."
(cdr root)) (cdr root))
'string-lessp)))) 'string-lessp))))
(defun ledger-command-at-point ()
"Do appropriate completion for current context."
(let ((context (mapcar*
(lambda(x) (if (symbolp x) (symbol-name x)))
(ledger-context-at-point))))
(cond
((string= "acct-transaction" (car context))
(concat (car context) "/" (nth 1 context)))
((string= "pmnt-transaction" (car context))
(concat (car context) "/" (nth 1 context)))
(t
(car context)))))
(defun ledger-complete-at-point () (defun ledger-complete-at-point ()
"Do appropriate completion for the thing at point." "Calls the right completion function for first argument completions."
(interactive) (ignore
(funcall (or (pcomplete-find-completion-function
(ledger-command-at-point))
pcomplete-default-completion-function))))
(defun pcomplete/ledger-mode/empty-line ()
"Complete when at empty line."
(ignore
(ledger-add-transaction (read-string "Transaction: "
(ledger-year-and-month)) (point))))
(defun pcomplete/ledger-mode/pmnt-transaction/date ()
"Complete when at date in transaction."
(ignore))
(defun pcomplete/ledger-mode/pmnt-transaction/payee ()
"Complete when at payee in transaction."
(while (pcomplete-here (while (pcomplete-here
(if (eq (save-excursion (if (eq (save-excursion
(ledger-thing-at-point)) 'transaction) (ledger-thing-at-point)) 'transaction)
@ -168,8 +197,24 @@ Return list."
(goto-char (line-end-position)) (goto-char (line-end-position))
(search-backward ";" (line-beginning-position) t) (search-backward ";" (line-beginning-position) t)
(skip-chars-backward " \t0123456789.,") (skip-chars-backward " \t0123456789.,")
(throw 'pcompleted t))) (throw 'pcompleted t)))))))
(ledger-accounts)))))
(defun pcomplete/ledger-mode/acct-transaction/indent ()
"Complete when at indent in transaction."
(ignore (ledger-thing-at-point)))
(defun pcomplete/ledger-mode/acct-transaction/account ()
"Complete when at account in transaction."
(set (make-local-variable 'pcomplete-termination-string) " ")
(pcomplete-here (ledger-accounts)))
(defun pcomplete/ledger-mode/acct-transaction/amount ()
"Complete when at amount in transaction."
(ignore (ledger-post-edit-amount)))
(defun pcomplete/ledger-mode/acct-transaction/comment ()
"Complete when at amount in transaction."
(pcomplete-here (ledger-find-metadata-in-buffer)))
(defun ledger-fully-complete-xact () (defun ledger-fully-complete-xact ()
"Completes a transaction if there is another matching payee in the buffer. "Completes a transaction if there is another matching payee in the buffer.

View file

@ -42,16 +42,7 @@
(defconst ledger-code-string "\\((.*)\\)?") (defconst ledger-code-string "\\((.*)\\)?")
(defconst ledger-payee-string "\\(.*\\)") (defconst ledger-payee-string "\\(.*\\)")
(defmacro ledger-line-regex (&rest elements) (defmacro ledger-single-line-config (&rest elements)
(let (regex-string)
(concat (dolist (e elements regex-string)
(setq regex-string
(concat regex-string
(eval
(intern
(concat "ledger-" (symbol-name e) "-string")))))) "[ \t]*$")))
(defmacro ledger-single-line-config2 (&rest elements)
"Take list of ELEMENTS and return regex and element list for use in context-at-point" "Take list of ELEMENTS and return regex and element list for use in context-at-point"
(let (regex-string) (let (regex-string)
`'(,(concat (dolist (e elements regex-string) `'(,(concat (dolist (e elements regex-string)
@ -62,23 +53,25 @@
(concat "ledger-" (symbol-name e) "-string")))))) "[ \t]*$") (concat "ledger-" (symbol-name e) "-string")))))) "[ \t]*$")
,elements))) ,elements)))
(defmacro ledger-single-line-config (&rest elements)
"Take list of ELEMENTS and return regex and element list for use in context-at-point"
`'(,(eval `(ledger-line-regex ,@elements))
,elements))
(defconst ledger-line-config (defconst ledger-line-config
(list (list 'xact (list (ledger-single-line-config date nil status nil code nil payee nil comment) (list
(ledger-single-line-config date nil status nil code nil payee) (list 'pmnt-transaction
(ledger-single-line-config date nil status nil payee))) (list (ledger-single-line-config date nil status nil code nil payee nil comment)
(list 'acct-transaction (list (ledger-single-line-config indent comment) (ledger-single-line-config date nil status nil code nil payee)
(ledger-single-line-config2 indent status account nil commodity amount nil comment) (ledger-single-line-config date nil status nil payee)
(ledger-single-line-config2 indent status account nil commodity amount) (ledger-single-line-config date nil code nil payee nil comment)
(ledger-single-line-config2 indent status account nil amount nil commodity comment) (ledger-single-line-config date nil code nil payee)
(ledger-single-line-config2 indent status account nil amount nil commodity) (ledger-single-line-config date nil payee)
(ledger-single-line-config2 indent status account nil amount) (ledger-single-line-config date)))
(ledger-single-line-config2 indent status account nil comment) (list 'acct-transaction
(ledger-single-line-config2 indent status account))))) (list (ledger-single-line-config indent comment)
(ledger-single-line-config indent status account nil commodity amount nil comment)
(ledger-single-line-config indent status account nil commodity amount)
(ledger-single-line-config indent status account nil amount nil commodity comment)
(ledger-single-line-config indent status account nil amount nil commodity)
(ledger-single-line-config indent status account nil amount)
(ledger-single-line-config indent status account nil comment)
(ledger-single-line-config indent status account)))))
(defun ledger-extract-context-info (line-type pos) (defun ledger-extract-context-info (line-type pos)
"Get context info for current line with LINE-TYPE. "Get context info for current line with LINE-TYPE.
@ -138,7 +131,7 @@ the fields in the line in a association list."
((memq first-char '(?\ ?\t)) ((memq first-char '(?\ ?\t))
(ledger-extract-context-info 'acct-transaction pos)) (ledger-extract-context-info 'acct-transaction pos))
((memq first-char '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) ((memq first-char '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
(ledger-extract-context-info 'xact pos)) (ledger-extract-context-info 'pmnt-transaction pos))
((equal first-char ?\=) ((equal first-char ?\=)
'(automated-xact nil nil)) '(automated-xact nil nil))
((equal first-char ?\~) ((equal first-char ?\~)

View file

@ -145,6 +145,11 @@ Can indent, complete or align depending on context."
(defvar ledger-mode-abbrev-table) (defvar ledger-mode-abbrev-table)
(defvar ledger-date-string-today
(format-time-string (or
(cdr (assoc "date-format" ledger-environment-alist))
ledger-default-date-format)))
(defun ledger-remove-effective-date () (defun ledger-remove-effective-date ()
"Removes the effective date from a transaction or posting." "Removes the effective date from a transaction or posting."
(interactive) (interactive)
@ -153,7 +158,7 @@ Can indent, complete or align depending on context."
(save-restriction (save-restriction
(narrow-to-region (point-at-bol) (point-at-eol)) (narrow-to-region (point-at-bol) (point-at-eol))
(beginning-of-line) (beginning-of-line)
(cond ((eq 'xact context) (cond ((eq 'pmnt-transaction context)
(re-search-forward ledger-iso-date-regexp) (re-search-forward ledger-iso-date-regexp)
(when (= (char-after) ?=) (when (= (char-after) ?=)
(let ((eq-pos (point))) (let ((eq-pos (point)))
@ -187,7 +192,7 @@ With a prefix argument, remove the effective date. "
(save-restriction (save-restriction
(narrow-to-region (point-at-bol) (point-at-eol)) (narrow-to-region (point-at-bol) (point-at-eol))
(cond (cond
((eq 'xact context) ((eq 'pmnt-transaction context)
(beginning-of-line) (beginning-of-line)
(re-search-forward ledger-iso-date-regexp) (re-search-forward ledger-iso-date-regexp)
(when (= (char-after) ?=) (when (= (char-after) ?=)
@ -320,7 +325,6 @@ With a prefix argument, remove the effective date. "
'ledger-parse-arguments) 'ledger-parse-arguments)
(set (make-local-variable 'pcomplete-command-completion-function) (set (make-local-variable 'pcomplete-command-completion-function)
'ledger-complete-at-point) 'ledger-complete-at-point)
(set (make-local-variable 'pcomplete-termination-string) "")
(add-hook 'post-command-hook 'ledger-highlight-xact-under-point nil t) (add-hook 'post-command-hook 'ledger-highlight-xact-under-point nil t)
(add-hook 'before-revert-hook 'ledger-occur-remove-all-overlays nil t) (add-hook 'before-revert-hook 'ledger-occur-remove-all-overlays nil t)