Add :lang beancount module
This commit is contained in:
parent
2d140a7a80
commit
8a083d1370
6 changed files with 219 additions and 1 deletions
|
@ -95,6 +95,7 @@ Modules that reconfigure or augment packages or features built into Emacs.
|
|||
Modules that bring support for a language or group of languages to Emacs.
|
||||
|
||||
+ [[file:../modules/lang/agda/README.org][agda]] =+local= - TODO
|
||||
+ [[file:../modules/lang/beancount/README.org][beancount]] =+lsp= - TODO
|
||||
+ [[file:../modules/lang/cc/README.org][cc]] =+lsp= - TODO
|
||||
+ [[file:../modules/lang/clojure/README.org][clojure]] =+lsp= - TODO
|
||||
+ common-lisp - TODO
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
|
||||
:lang
|
||||
;;agda ; types of types of types of types...
|
||||
;;beancount ; the accounting system in Emacs
|
||||
;;cc ; C/C++/Obj-C madness
|
||||
;;clojure ; java with a lisp
|
||||
;;common-lisp ; if you've seen one lisp, you've seen them all
|
||||
|
@ -140,7 +141,7 @@
|
|||
;;latex ; writing papers in Emacs has never been so fun
|
||||
;;lean
|
||||
;;factor
|
||||
;;ledger ; an accounting system in Emacs
|
||||
;;ledger ; an other accounting system in Emacs
|
||||
;;lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
;;nim ; python + lisp at the speed of c
|
||||
|
|
53
modules/lang/beancount/README.org
Normal file
53
modules/lang/beancount/README.org
Normal file
|
@ -0,0 +1,53 @@
|
|||
#+TITLE: lang/beancount
|
||||
#+DATE: April 13, 2021
|
||||
#+SINCE: v3.0.0
|
||||
#+STARTUP: inlineimages nofold
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#maintainers][Maintainers]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
* Description
|
||||
This module adds support for [[https://beancount.github.io/][Beancount]] to Emacs. Beancount, like ledger, lets
|
||||
you [[https://plaintextaccounting.org/][manage your money in plain text]].
|
||||
|
||||
+ Supports [[https://github.com/polarmutex/beancount-language-server][beancount-language-server]] (if module is enabled with the =+lsp=
|
||||
flag).
|
||||
|
||||
** Maintainers
|
||||
This module has no dedicated maintainers.
|
||||
|
||||
** Module Flags
|
||||
+ =+lsp= Enable support for [beancount-language-server]. Requires Doom's =:tools
|
||||
lsp= module.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/beancount/beancount-mode][beancount]]
|
||||
|
||||
** Hacks
|
||||
+ Associates the material =attach_money= icon with *.beancount files in the
|
||||
=all-the-icons= package.
|
||||
|
||||
* Prerequisites
|
||||
This module has no hard prerequisites, but assumes you have [[https://github.com/beancount/beancount][beancount]] installed
|
||||
in order to generate reports with ~bean-report~.
|
||||
|
||||
#+begin_quote
|
||||
Also: the ~beancount-fava~ command requires [[https://beancount.github.io/fava/][fava]].
|
||||
#+end_quote
|
||||
|
||||
* TODO Features
|
||||
# An in-depth list of features, how to use them, and their dependencies.
|
||||
|
||||
* TODO Configuration
|
||||
# How to configure this module, including common problems and how to address them.
|
||||
|
||||
* TODO Troubleshooting
|
||||
# Common issues and their solution, or places to look for help.
|
127
modules/lang/beancount/autoload.el
Normal file
127
modules/lang/beancount/autoload.el
Normal file
|
@ -0,0 +1,127 @@
|
|||
;;; lang/beancount/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Helpers
|
||||
|
||||
;; Lifted from ledger
|
||||
(defconst +beancount--payee-any-status-regex
|
||||
"^[0-9]+[-/][-/.=0-9]+\\(\\s-+\\*\\)?\\(\\s-+(.*?)\\)?\\s-+\\(.+?\\)\\s-*\\(;\\|$\\)")
|
||||
|
||||
(defun +beancount--sort-startkey ()
|
||||
"Return the actual date so the sort subroutine doesn't sort on the entire first line."
|
||||
(buffer-substring-no-properties (point) (+ 10 (point))))
|
||||
|
||||
(defun +beancount--navigate-next-xact ()
|
||||
"Move point to beginning of next xact."
|
||||
;; make sure we actually move to the next xact, even if we are the beginning
|
||||
;; of one now.
|
||||
(if (looking-at +beancount--payee-any-status-regex)
|
||||
(forward-line))
|
||||
(if (re-search-forward +beancount--payee-any-status-regex nil t)
|
||||
(goto-char (match-beginning 0))
|
||||
(goto-char (point-max))))
|
||||
|
||||
(defun +beancount--navigate-start-xact-or-directive-p ()
|
||||
"Return t if at the beginning of an empty or all-whitespace line."
|
||||
(not (looking-at "[ \t]\\|\\(^$\\)")))
|
||||
|
||||
(defun +beancount--navigate-next-xact-or-directive ()
|
||||
"Move to the beginning of the next xact or directive."
|
||||
(interactive)
|
||||
(beginning-of-line)
|
||||
(if (+beancount--navigate-start-xact-or-directive-p) ; if we are the start of an xact, move forward to the next xact
|
||||
(progn
|
||||
(forward-line)
|
||||
(if (not (+beancount--navigate-start-xact-or-directive-p)) ; we have moved forward and are not at another xact, recurse forward
|
||||
(+beancount--navigate-next-xact-or-directive)))
|
||||
(while (not (or (eobp) ; we didn't start off at the beginning of an xact
|
||||
(+beancount--navigate-start-xact-or-directive-p)))
|
||||
(forward-line))))
|
||||
|
||||
(defun +beancount--navigate-next-xact ()
|
||||
"Move point to beginning of next xact."
|
||||
;; make sure we actually move to the next xact, even if we are the
|
||||
;; beginning of one now.
|
||||
(if (looking-at +beancount--payee-any-status-regex)
|
||||
(forward-line))
|
||||
(if (re-search-forward +beancount--payee-any-status-regex nil t)
|
||||
(goto-char (match-beginning 0))
|
||||
(goto-char (point-max))))
|
||||
|
||||
(defun +beancount--navigate-beginning-of-xact ()
|
||||
"Move point to the beginning of the current xact."
|
||||
;; need to start at the beginning of a line in case we are in the first line of an xact already.
|
||||
(beginning-of-line)
|
||||
(let ((sreg (concat "^[=~[:digit:]]")))
|
||||
(unless (looking-at sreg)
|
||||
(re-search-backward sreg nil t)
|
||||
(beginning-of-line)))
|
||||
(point))
|
||||
|
||||
(defun +beancount--navigate-end-of-xact ()
|
||||
"Move point to end of xact."
|
||||
(+beancount--navigate-next-xact-or-directive)
|
||||
(re-search-backward ".$")
|
||||
(end-of-line)
|
||||
(point))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +beancount/sort-buffer (&optional reverse)
|
||||
"Sort all transactions in the buffer.
|
||||
If REVERSE (the prefix arg) is non-nil, sort them in reverse."
|
||||
(interactive "P")
|
||||
(+beancount/sort-region (point-min) (point-max) reverse))
|
||||
|
||||
;;;###autoload
|
||||
(defun +beancount/sort-region (beg end &optional reverse)
|
||||
"Sort the transactions inside BEG and END.
|
||||
If REVERSE (the prefix arg) is non-nil, sort the transactions in reverst order."
|
||||
(interactive
|
||||
(list (region-beginning)
|
||||
(region-end)
|
||||
(and current-prefix-arg t)))
|
||||
(let* ((new-beg beg)
|
||||
(new-end end)
|
||||
(bounds (save-excursion
|
||||
(list (+beancount--navigate-beginning-of-xact)
|
||||
(+beancount--navigate-end-of-xact))))
|
||||
(point-delta (- (point) (car bounds)))
|
||||
(target-xact (buffer-substring (car bounds) (cadr bounds)))
|
||||
(inhibit-modification-hooks t))
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(goto-char beg)
|
||||
;; make sure beg of region is at the beginning of a line
|
||||
(beginning-of-line)
|
||||
;; make sure point is at the beginning of a xact
|
||||
(unless (looking-at +beancount--payee-any-status-regex)
|
||||
(+beancount--navigate-next-xact))
|
||||
(setq new-beg (point))
|
||||
(goto-char end)
|
||||
(+beancount--navigate-next-xact)
|
||||
;; make sure end of region is at the beginning of next record after the
|
||||
;; region
|
||||
(setq new-end (point))
|
||||
(narrow-to-region new-beg new-end)
|
||||
(goto-char new-beg)
|
||||
(let ((inhibit-field-text-motion t))
|
||||
(sort-subr
|
||||
reverse
|
||||
'+beancount--navigate-next-xact
|
||||
'+beancount--navigate-end-of-xact
|
||||
'+beancount--sort-startkey))))
|
||||
(goto-char (point-min))
|
||||
(re-search-forward (regexp-quote target-xact))
|
||||
(goto-char (+ (match-beginning 0) point-delta))))
|
||||
|
||||
(defvar compilation-read-command)
|
||||
;;;###autoload
|
||||
(defun +beancount/balance ()
|
||||
"Run 'bean-report bal'."
|
||||
(interactive)
|
||||
(let (compilation-read-command)
|
||||
(beancount--run "bean-report" buffer-file-name "bal")))
|
29
modules/lang/beancount/config.el
Normal file
29
modules/lang/beancount/config.el
Normal file
|
@ -0,0 +1,29 @@
|
|||
;;; lang/beancount/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! beancount-mode
|
||||
:mode "\\.beancount\\'"
|
||||
:init
|
||||
(add-hook 'beancount-mode-hook #'outline-minor-mode)
|
||||
|
||||
(after! all-the-icons
|
||||
(add-to-list 'all-the-icons-icon-alist
|
||||
'("\\.beancount\\'" all-the-icons-material "attach_money" :face all-the-icons-lblue))
|
||||
(add-to-list 'all-the-icons-mode-icon-alist
|
||||
'(beancount-mode all-the-icons-material "attach_money" :face all-the-icons-lblue)))
|
||||
:config
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'beancount-mode-local-vars-hook #'lsp!))
|
||||
|
||||
(setq beancount-electric-currency t)
|
||||
|
||||
(map! :map beancount-mode-map
|
||||
:localleader
|
||||
"b" #'+beancount/balance
|
||||
"c" #'beancount-check
|
||||
"l" #'beancount-linked
|
||||
"q" #'beancount-query
|
||||
"x" #'beancount-context
|
||||
(:prefix ("i" . "insert")
|
||||
"a" #'beancount-insert-account
|
||||
"p" #'beancount-insert-prices
|
||||
"d" #'beancount-insert-date)))
|
7
modules/lang/beancount/packages.el
Normal file
7
modules/lang/beancount/packages.el
Normal file
|
@ -0,0 +1,7 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/beancount/packages.el
|
||||
|
||||
(package! beancount
|
||||
:recipe (:host github
|
||||
:repo "beancount/beancount-mode")
|
||||
:pin "3c04745fa539c25dc007683ad257239067c24cfe")
|
Loading…
Add table
Add a link
Reference in a new issue