如果你用 Emacs + Beancount 来记账,那你应该有用 beancount-mode 这个包。它可以帮助我们在记账的时候从当前 buffer 中提取出已定义的账户,当我们下达 M-x beancount-insert-account
命令的时候,它会弹出 minibuffer 来让我们模糊选择使用哪个账户,从而提高记账效率。
但是它只能从当前 buffer 中搜集账户。而随着我们账本的扩大,一般我们会单独出一个账户文件(甚至几个文件)来记录 open close 账户的指令,这种情况下 beancount-mode 的可用性就大大降低了。
好在 cnsunyour's fork 已经实现了这个功能,但是它与 upstream 有一段时间没有同步了,不利于后续跟进使用 upstream 版本。最近花了点时间,把这部分的代码单独抽离出来,通过 Emacs Advice 的机制来实现,这样就还可以继续使用 upstream 版本。
代码如下:
(defvar beancount-account-files nil
"List of account files")
(defun w/beancount--collect-accounts-from-files (oldfun regex n)
(let ((keys (funcall oldfun regex n))
(hash (make-hash-table :test 'equal)))
(dolist (key keys)
(puthash key nil hash))
;; collect accounts from files
(save-excursion
(dolist (f beancount-account-files)
(with-current-buffer (find-file-noselect f)
(goto-char (point-min))
(while (re-search-forward beancount-account-regexp nil t)
(puthash (match-string-no-properties n) nil hash)))))
(hash-table-keys hash)))
(advice-add #'beancount-collect
:around #'w/beancount--collect-accounts-from-files
'((name . "collect accounts from files as well")))
把上面代码 copy 到你的配置中,然后通过 (setq beancount-account-files '("/path/to/accounts.bean"))
来把你的账户文件配置进来。现在你就可以通过 M-x beancount-insert-account
愉快地从自定义的账户文件中补全了。(如果你在记账的时候进行以上配置,你可能需要 revert the current beancount buffer 来让配置生效)。
P.S. 如果你不喜欢以 ido 的风格进行账户补全,那么通过 (setq beancount-use-ido nil)
就可以让 ivy 之类的补全框架来接管补全界面。