I decided to create an example of a user-defined function magic-money-xf <https://github.com/tesujimath/limabean/blob/main/examples/clj/user.clj#L15> which does what previously would have required a plugin. Hopefully this will provide insight for anyone thinking a lack of plugins might be a show-stopper.
This example function (a Clojure transducer) takes the fully resolved directives which are produced by the booking algorithm, and inserts additional directives as follows. After every open directive, a new transaction is inserted, adding money to the account from some magical benefactor. And before the first such open, the open directive for the magical equity account itself is inserted. Example use as follows, making use of small.beancount <https://github.com/tesujimath/limabean/blob/main/examples/beancount/small.beancount> : kiri> limabean --beanfile examples/beancount/small.beancount [Rebel readline] Type :repl/help for online help info [limabean] 4 directives loaded from examples/beancount/small.beancount user=> (require '[clojure.pprint :refer [pprint]]) user=> (pprint *directives*) [{:date #object[java.time.LocalDate 0x6b283550 "2016-03-01"], :dct :open, :acc "Assets:Bank:Current"} {:date #object[java.time.LocalDate 0x357849a2 "2016-03-01"], :dct :open, :acc "Expenses:Groceries"} {:date #object[java.time.LocalDate 0xcda6100 "2023-05-29"], :dct :txn, :flag "*", :payee "New World", :postings [{:acc "Expenses:Groceries", :units 10.00M, :cur "NZD"} {:acc "Assets:Bank:Current", :units -10.00M, :cur "NZD"}]} {:date #object[java.time.LocalDate 0x21e896f6 "2023-05-30"], :dct :txn, :flag "*", :payee "Countdown", :postings [{:acc "Expenses:Groceries", :units 17.50M, :cur "NZD"} {:acc "Assets:Bank:Current", :units -17.50M, :cur "NZD"}]}] Apologies for the lack of nicer output formatting for directives, but hopefully you can see a couple of open directives followed by a couple of transactions, matching what was in the input file <https://github.com/tesujimath/limabean/blob/main/examples/beancount/small.beancount> . And here's where we make our new list of directives with the magical money, using that magic-money-xf <https://github.com/tesujimath/limabean/blob/main/examples/clj/user.clj#L15> function. Note that it's a new list, so must be passed in explicitly instead of the default *directives* where we want this one. user=> (def directives-with-magical-us (into [] (magic-money-xf {:units 1000.00M :cur "USD" :acc "Equity:Rich-American-Uncle"}) *directives*)) user=> (count directives-with-magical-us) 7 user=> (pprint directives-with-magical-us) [{:date #object[java.time.LocalDate 0x6b283550 "2016-03-01"], :dct :open, :acc "Equity:Rich-American-Uncle"} {:date #object[java.time.LocalDate 0x6b283550 "2016-03-01"], :dct :open, :acc "Assets:Bank:Current"} {:date #object[java.time.LocalDate 0x6b283550 "2016-03-01"], :dct :txn, :postings [{:acc "Equity:Rich-American-Uncle", :units -1000.00M, :cur "USD"} {:acc "Assets:Bank:Current", :units 1000.00M, :cur "USD", :payee "magical benefactor"}]} {:date #object[java.time.LocalDate 0x357849a2 "2016-03-01"], :dct :open, :acc "Expenses:Groceries"} {:date #object[java.time.LocalDate 0x357849a2 "2016-03-01"], :dct :txn, :postings [{:acc "Equity:Rich-American-Uncle", :units -1000.00M, :cur "USD"} {:acc "Expenses:Groceries", :units 1000.00M, :cur "USD", :payee "magical benefactor"}]} {:date #object[java.time.LocalDate 0xcda6100 "2023-05-29"], :dct :txn, :flag "*", :payee "New World", :postings [{:acc "Expenses:Groceries", :units 10.00M, :cur "NZD"} {:acc "Assets:Bank:Current", :units -10.00M, :cur "NZD"}]} {:date #object[java.time.LocalDate 0x21e896f6 "2023-05-30"], :dct :txn, :flag "*", :payee "Countdown", :postings [{:acc "Expenses:Groceries", :units 17.50M, :cur "NZD"} {:acc "Assets:Bank:Current", :units -17.50M, :cur "NZD"}]}] So now we have a new open directive for the magical equity account, and a couple of new transactions, for those opening benefits. If only the real world worked like this! Also: user=> (show (journal)) 2023-05-29 Expenses:Groceries New World 10.00 NZD 10.00 NZD 2023-05-29 Assets:Bank:Current New World -10.00 NZD 2023-05-30 Expenses:Groceries Countdown 17.50 NZD 17.50 NZD 2023-05-30 Assets:Bank:Current Countdown -17.50 NZD :ok user=> (show (journal :directives directives-with-magical-us)) 2016-03-01 Equity:Rich-American-Uncle -1000.00 USD -1000.00 USD 2016-03-01 Assets:Bank:Current magical benefactor 1000.00 USD 2016-03-01 Equity:Rich-American-Uncle -1000.00 USD -1000.00 USD 2016-03-01 Expenses:Groceries magical benefactor 1000.00 USD 2023-05-29 Expenses:Groceries New World 10.00 NZD 10.00 NZD 2023-05-29 Assets:Bank:Current New World -10.00 NZD 2023-05-30 Expenses:Groceries Countdown 17.50 NZD 17.50 NZD 2023-05-30 Assets:Bank:Current Countdown -17.50 NZD :ok I find this facility to bring your own functions directly into the user interface to be quite compelling. 😁 Apologies for the long post if I exceeded anyone's level of interest! Full disclosure: this is all very new and really not yet stabilised. The behaviour I am showing off here is on the main branch of limabean <https://github.com/tesujimath/limabean> but not in the most recent release 0.2.7. So if you want to have a play, clone the repo, and read the docs on how to run a development version <https://github.com/tesujimath/limabean/blob/main/clj/doc/50-development.md> (you'll need Clojure tools but not Rust). But I'll probably be cutting another release next week with this and some other improvements. cheers, Simon On Sat, 28 Feb 2026 at 09:56, [email protected] <[email protected]> wrote: > > I believe this approach makes sense in limabean because the user interface > is a full-blown programming language, Clojure, and you can do whatever you > need with the list of fully resolved directives that are exposed there > after loading the beanfile. > > > Makes sense. > > > > Plugins would justify their existence by a need to modify the transactions > earlier, before the booking algorithm has run. Are there compelling use > cases for this? > > > Some examples: anything that opens > <https://github.com/redstreet/beancount_reds_plugins/tree/main/beancount_reds_plugins/opengroup#readme>, > closes > <https://github.com/redstreet/beancount_reds_plugins/tree/main/beancount_reds_plugins/autoclose_tree#readme>, > or renames > <https://github.com/redstreet/beancount_reds_plugins/tree/main/beancount_reds_plugins/rename_accounts#readme> > accounts. YMMV, of course. > > > -- > You received this message because you are subscribed to the Google Groups > "Beancount" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion visit > https://groups.google.com/d/msgid/beancount/699b4206-605b-4baf-8df6-3fd0ecf8653cn%40googlegroups.com > <https://groups.google.com/d/msgid/beancount/699b4206-605b-4baf-8df6-3fd0ecf8653cn%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Beancount" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/beancount/CAFhGSbt5EACKHdJpXXHL0%3D%3DVn0DieT1crzr7cD0UQ%3DqCUv_cXw%40mail.gmail.com.
