From 5235e16f543506b309b05d57f76312a5724451ca Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Wed, 22 Jul 2026 16:23:58 +0300 Subject: [PATCH] scm: support configuration Support a configuration function, with the system-configuration. Update docs. Add a tests for language, using the configuration to see if we support it. --- scm/mu-scm-store.cc | 3 ++- scm/mu-scm-test.scm | 4 ++++ scm/mu-scm.cc | 48 ++++++++++++++++++++++++++++++++++---- scm/mu-scm.scm | 22 ++++++++++++++---- scm/mu-scm.texi | 56 +++++++++++++++++++++++++++------------------ 5 files changed, 100 insertions(+), 33 deletions(-) diff --git a/scm/mu-scm-store.cc b/scm/mu-scm-store.cc index 47408245..3f5a2540 100644 --- a/scm/mu-scm-store.cc +++ b/scm/mu-scm-store.cc @@ -55,7 +55,8 @@ subr_cc_store_alist(SCM store_scm) try { continue; const auto str{conf.as_display_string(prop)}; - const auto name{make_symbol(prop.name)}; + const auto name{make_symbol(mu_format("{}{}", prop.name, + prop.type == Type::Boolean ? "?" : ""))}; const auto val = std::invoke([&]() { switch (prop.type) { case Type::Number: diff --git a/scm/mu-scm-test.scm b/scm/mu-scm-test.scm index ee2c9773..0acbcba8 100644 --- a/scm/mu-scm-test.scm +++ b/scm/mu-scm-test.scm @@ -108,6 +108,10 @@ (test-equal '((email . "anon@example.com") (name . "Mickey Mouse")) (car (assoc-ref alist 'from))) + ;; language + (test-equal (language msg) + (if (assoc-ref (configuration) 'language-enabled?) 'en nil)) + ;; cc, bc, labels (test-equal '() (cc msg)) (test-equal '() (bcc msg)) diff --git a/scm/mu-scm.cc b/scm/mu-scm.cc index 1440417a..7920a4da 100644 --- a/scm/mu-scm.cc +++ b/scm/mu-scm.cc @@ -32,6 +32,8 @@ #include "mu-scm-types.hh" +#include "mu-config.hh" + #ifdef HAVE_PTHREAD_SETNAME_NP #include #endif @@ -44,7 +46,7 @@ SCM mu_mod; // The mu module } /** - * Create a plist for the relevant option items + * Create an alist for the relevant option items (i.e., command-line parameters) * * @param opts */ @@ -52,16 +54,51 @@ static void init_options(const Options& opts) { SCM scm_opts = alist_add(SCM_EOL, - make_symbol("verbose"), opts.verbose, - make_symbol("debug"), opts.debug, - make_symbol("quiet"), opts.quiet); + make_symbol("verbose?"), opts.verbose, + make_symbol("debug?"), opts.debug, + make_symbol("quiet?"), opts.quiet); if (opts.muhome.empty()) scm_opts = alist_add(scm_opts, make_symbol("mu-home"), SCM_BOOL_F); else scm_opts = alist_add(scm_opts, make_symbol("mu-home"), opts.muhome); - scm_c_define("%options", scm_opts); + + scm_c_define("%options", scm_reverse_x(scm_opts, SCM_EOL)); +} + +/** + * Create an alist for the relevant system-configuration parameters + */ +static void +init_configuration() +{ + SCM conf{SCM_EOL}; + + for (const auto& prop: Config::properties) { + + if (none_of(prop.flags & Property::Flags::System)) + continue; + + const auto val{Config::default_value(prop)}; + if (!val) + continue; + + switch(prop.type) { + case Config::Type::Boolean: + conf = alist_add(conf, make_symbol(mu_format("{}?", prop.name, "?")), + Config::decode(*val)); + break; + case Config::Type::String: + conf = alist_add(conf, make_symbol(prop.name), *val); + break; + default: + // other types are not used here yet. + break; + } + } + + scm_c_define("%configuration", scm_reverse_x(conf, SCM_EOL)); } static void @@ -179,6 +216,7 @@ init_module_mu(void* data) const ModMuData& conf{*reinterpret_cast(data)}; init_options(conf.opts); + init_configuration(); init_misc(); init_subrs(); diff --git a/scm/mu-scm.scm b/scm/mu-scm.scm index 79388c22..0efc7b92 100644 --- a/scm/mu-scm.scm +++ b/scm/mu-scm.scm @@ -1,4 +1,4 @@ -;; Copyright (C) 2025 Dirk-Jan C. Binnema +;; Copyright (C) 2025-2026 Dirk-Jan C. Binnema ;; ;; This program is free software; you can redistribute it and/or modify it ;; under the terms of the GNU General Public License as published by the @@ -100,8 +100,10 @@ ;; Other ;; misc - %options - ;; %preferences + options + configuration + + %options ;; deprecated, use (options) ;; logging debug @@ -621,9 +623,20 @@ init'. Uses the default-store." ;; ;; The alist maps symbols to values; a value of #f indicates that the value is at ;; its default. -%options ;; defined in c++ +%options ;; defined in c++ (public, but deprecated) (set-documentation! '%options "Alist with the command-line parameters.") +(define (options) + "Get an alist with the options that \"mu\" started with. That as, command-line + arguments, defaults, environment." + %options) + +%configuration ;; defined in c++ +(set-documentation! '%configuration + "Alist with the mu system configuration parameters.") +(define (configuration) + "Alist with the mu system configuration parameters.." + %configuration) (define %preferences '( (short-date . "%F %T") @@ -684,7 +697,6 @@ UTC time. (strftime format t)) #f))) - ;; Logging to mu's log (define (mlog level frmstr . args) diff --git a/scm/mu-scm.texi b/scm/mu-scm.texi index 560bc665..86b1ea3e 100644 --- a/scm/mu-scm.texi +++ b/scm/mu-scm.texi @@ -126,22 +126,20 @@ optional. To build @t{mu} with SCM support, first you need to ensure you have installed the required Guile development packages. The details of getting those vary across environments / distributions, e.g.: on Fedora (as root): - @example # dnf install guile30-devel @end example - -or on Debian/Ubuntu: +or on Debian/Ubuntu and derivatives: @example $ sudo apt install guile-3.0-dev @end example -With those packages in place, you can (re)build @t{mu} and @t{mu-scm} should be -built automatically if you did @emph{not} explicitly disable it. +With those packages in place, a (re)build @t{mu} and @t{mu-scm} should +automatically build the SCM-support, unless you explicitly disabled it. -Parts of @t{mu-scm} depend on @t{mu} being @emph{installed}, not just built; -however, you can still use it un-installed as well by setting an environment -variable @t{MU_SCM_DIR} to the source-directory, e.g. +By default,@t{mu-scm} expects @t{mu} being @emph{installed}, not just +@emph{built}; however, you can still use it un-installed as well by setting the +environment variable @t{MU_SCM_DIR} to the path to the source-directory, e.g. @t{/home/user/sources/mu/scm}. @node Starting the REPL @@ -150,7 +148,9 @@ variable @t{MU_SCM_DIR} to the source-directory, e.g. After installing @t{mu}, you can check the output of @command{mu info}. If @t{mu-scm} is available, in the table you should find a line: @example -| scm-support | yes | GNU Guile 3.x support (new)? | ++------------------+-------------+--------------------------------------------+ +| scm-enabled | yes | Is SCM/Guile supported? | ++------------------+-------------+--------------------------------------------+ @end example You can then start an interactive shell, also known as the @@ -488,8 +488,8 @@ More fields may be added. @deffn {Scheme Procedure} root-maildir @end deffn -Get the root maildir directory, that is, the root of under the directory under -which all messages reside. +Get the root maildir directory, that is, the root directory under which all +messages reside. This is equivalent to @code{(assoc-ref (store->alist) 'root-maildir)}. @@ -946,22 +946,34 @@ For example: @c Get the message's s-expression. @c @t{mu} caches an s-expression for each message; this was designed as an -@c optimization for @code{mu4e}, but @t{mu-scm} uses it as well. The details of this -@c s-expression (a property-list) are internal to @t{mu} (so do not base your next -@c billion-dollar startup on it), but it can be useful for development and -@c debugging. +@c optimization for @code{mu4e}, but @t{mu-scm} uses it as well. The details of +@c this s-expression (a property-list) are internal to @t{mu} (so do not base +@c your next billion-dollar startup on it), but it can be useful for development +@c and debugging. @node Miscellaneous @section Miscellaneous -@defvar %options -@end defvar - -An association-list (alist) of general options passed to @command{mu scm} or -their default values. +@deffn {Scheme Procedure} options +@end deffn +Get an association-list (alist) of general options passed to @command{mu scm} or +their default values. This might look something like: @lisp - %options -=> ((mu-home . #f) (quiet . #f) (debug . #f) (verbose . #f)) +(options) +=> ((verbose? . #f) (debug? . #f) (quiet? . #f) (mu-home . #f)) +@end lisp + +Other options may be added. + +@deffn {Scheme Procedure} configuration +@end deffn + +An association-list (alist) of the @t{mu} system configuration. This might look +something like: +@lisp +(configuration) +((mu-version . "1.14.3") (xapian-version . "1.4.30") (glib-version . "2.88.2") + (gmime-version . "3.2.15") (scm-enabled? . #t) (language-enabled? . #t)) @end lisp @c @defvar %preferences