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.
This commit is contained in:
Dirk-Jan C. Binnema
2026-07-22 16:23:58 +03:00
committed by Seth Ladygo
parent 31b0fd45c2
commit 5235e16f54
5 changed files with 100 additions and 33 deletions

View File

@ -55,7 +55,8 @@ subr_cc_store_alist(SCM store_scm) try {
continue; continue;
const auto str{conf.as_display_string(prop)}; 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([&]() { const auto val = std::invoke([&]() {
switch (prop.type) { switch (prop.type) {
case Type::Number: case Type::Number:

View File

@ -108,6 +108,10 @@
(test-equal '((email . "anon@example.com") (name . "Mickey Mouse")) (test-equal '((email . "anon@example.com") (name . "Mickey Mouse"))
(car (assoc-ref alist 'from))) (car (assoc-ref alist 'from)))
;; language
(test-equal (language msg)
(if (assoc-ref (configuration) 'language-enabled?) 'en nil))
;; cc, bc, labels ;; cc, bc, labels
(test-equal '() (cc msg)) (test-equal '() (cc msg))
(test-equal '() (bcc msg)) (test-equal '() (bcc msg))

View File

@ -32,6 +32,8 @@
#include "mu-scm-types.hh" #include "mu-scm-types.hh"
#include "mu-config.hh"
#ifdef HAVE_PTHREAD_SETNAME_NP #ifdef HAVE_PTHREAD_SETNAME_NP
#include <pthread.h> #include <pthread.h>
#endif #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 * @param opts
*/ */
@ -52,16 +54,51 @@ static void
init_options(const Options& opts) init_options(const Options& opts)
{ {
SCM scm_opts = alist_add(SCM_EOL, SCM scm_opts = alist_add(SCM_EOL,
make_symbol("verbose"), opts.verbose, make_symbol("verbose?"), opts.verbose,
make_symbol("debug"), opts.debug, make_symbol("debug?"), opts.debug,
make_symbol("quiet"), opts.quiet); make_symbol("quiet?"), opts.quiet);
if (opts.muhome.empty()) if (opts.muhome.empty())
scm_opts = alist_add(scm_opts, make_symbol("mu-home"), SCM_BOOL_F); scm_opts = alist_add(scm_opts, make_symbol("mu-home"), SCM_BOOL_F);
else else
scm_opts = alist_add(scm_opts, make_symbol("mu-home"), opts.muhome); 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<Config::Type::Boolean>(*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 static void
@ -179,6 +216,7 @@ init_module_mu(void* data)
const ModMuData& conf{*reinterpret_cast<ModMuData*>(data)}; const ModMuData& conf{*reinterpret_cast<ModMuData*>(data)};
init_options(conf.opts); init_options(conf.opts);
init_configuration();
init_misc(); init_misc();
init_subrs(); init_subrs();

View File

@ -1,4 +1,4 @@
;; Copyright (C) 2025 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Copyright (C) 2025-2026 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; ;;
;; This program is free software; you can redistribute it and/or modify it ;; 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 ;; under the terms of the GNU General Public License as published by the
@ -100,8 +100,10 @@
;; Other ;; Other
;; misc ;; misc
%options options
;; %preferences configuration
%options ;; deprecated, use (options)
;; logging ;; logging
debug 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 ;; The alist maps symbols to values; a value of #f indicates that the value is at
;; its default. ;; its default.
%options ;; defined in c++ %options ;; defined in c++ (public, but deprecated)
(set-documentation! '%options (set-documentation! '%options
"Alist with the command-line parameters.") "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 (define %preferences
'( (short-date . "%F %T") '( (short-date . "%F %T")
@ -684,7 +697,6 @@ UTC time.
(strftime format t)) (strftime format t))
#f))) #f)))
;; Logging to mu's log ;; Logging to mu's log
(define (mlog level frmstr . args) (define (mlog level frmstr . args)

View File

@ -126,22 +126,20 @@ optional.
To build @t{mu} with SCM support, first you need to ensure you have installed 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 the required Guile development packages. The details of getting those vary
across environments / distributions, e.g.: on Fedora (as root): across environments / distributions, e.g.: on Fedora (as root):
@example @example
# dnf install guile30-devel # dnf install guile30-devel
@end example @end example
or on Debian/Ubuntu and derivatives:
or on Debian/Ubuntu:
@example @example
$ sudo apt install guile-3.0-dev $ sudo apt install guile-3.0-dev
@end example @end example
With those packages in place, you can (re)build @t{mu} and @t{mu-scm} should be With those packages in place, a (re)build @t{mu} and @t{mu-scm} should
built automatically if you did @emph{not} explicitly disable it. 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; By default,@t{mu-scm} expects @t{mu} being @emph{installed}, not just
however, you can still use it un-installed as well by setting an environment @emph{built}; however, you can still use it un-installed as well by setting the
variable @t{MU_SCM_DIR} to the source-directory, e.g. environment variable @t{MU_SCM_DIR} to the path to the source-directory, e.g.
@t{/home/user/sources/mu/scm}. @t{/home/user/sources/mu/scm}.
@node Starting the REPL @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 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: @t{mu-scm} is available, in the table you should find a line:
@example @example
| scm-support | yes | GNU Guile 3.x support (new)? | +------------------+-------------+--------------------------------------------+
| scm-enabled | yes | Is SCM/Guile supported? |
+------------------+-------------+--------------------------------------------+
@end example @end example
You can then start an interactive shell, also known as the 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 @deffn {Scheme Procedure} root-maildir
@end deffn @end deffn
Get the root maildir directory, that is, the root of under the directory under Get the root maildir directory, that is, the root directory under which all
which all messages reside. messages reside.
This is equivalent to @code{(assoc-ref (store->alist) 'root-maildir)}. 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 Get the message's s-expression.
@c @t{mu} caches an s-expression for each message; this was designed as an @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 optimization for @code{mu4e}, but @t{mu-scm} uses it as well. The details of
@c s-expression (a property-list) are internal to @t{mu} (so do not base your next @c this s-expression (a property-list) are internal to @t{mu} (so do not base
@c billion-dollar startup on it), but it can be useful for development and @c your next billion-dollar startup on it), but it can be useful for development
@c debugging. @c and debugging.
@node Miscellaneous @node Miscellaneous
@section Miscellaneous @section Miscellaneous
@defvar %options @deffn {Scheme Procedure} options
@end defvar @end deffn
Get an association-list (alist) of general options passed to @command{mu scm} or
An association-list (alist) of general options passed to @command{mu scm} or their default values. This might look something like:
their default values.
@lisp @lisp
%options (options)
=> ((mu-home . #f) (quiet . #f) (debug . #f) (verbose . #f)) => ((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 @end lisp
@c @defvar %preferences @c @defvar %preferences