[neomutt-devel] [PATCH 1/2] Fix $reply_regex

наб nabijaczleweli at nabijaczleweli.xyz
Sat Dec 23 17:53:07 CET 2023


On Sat, Dec 23, 2023 at 02:54:35PM +0000, Richard Russon wrote:
> > ("config: fix flag overlaps") didn't
> Well spotted!
> 
> Damn, damn, damn!
> I spent quite a bit of time checking them.
> 
> Thanks for the patch; I've decided on a different solution.
> I've killed the R_ flags entirely.
> - PR #4146 -- config: factor out R_ flags
>   https://github.com/neomutt/neomutt/pull/4146
> 
> They're a leftover from the bad-old Mutt days.
> 
> Instead of Index-specific flags, the Index now explicitly checks for
> config that affects it.
> 
> It's not terribly efficient, but it'll do for now.
I think there's probably some value in keeping this all in the central
config, but a single 32-bit(!) bitfield is has clearly overstayed its
welcome, and having a separate LUT is just dodging the issue.

What follows is a diff that partly builds (41 files don't,
but most of them will be probably as trivial as init.c was)
that turns the blob into actual structured data,
which it is but pretends not to be.

The declaration machinery is slightly more DSLy than it used to be,
but the domains are clear now. Do notice just /how much/ shit there is,
but this is mostly hidden by being strewn around and inconsistent
nomenclature.

(cs_register_variables() is always called with DT_NO_FLAGS (0)
 so I mechanically just deleted that argument.

   #define DT_INHERIT_ACC   (1 << 12) ///< Config item can be Account-specific
   #define DT_INHERIT_MBOX  (1 << 13) ///< Config item can be Mailbox-specific
 and
   #define DT_DISABLED       (1 << 30)  ///< Config item is disabled
 are all unused (first two never checked, latter never ser)
 so I just removed them.)
-- >8 --
diff --git a/alias/config.c b/alias/config.c
index 57e2889e..9674bace 100644
--- a/alias/config.c
+++ b/alias/config.c
@@ -73,5 +73,5 @@ static struct ConfigDef AliasVars[] = {
  */
 bool config_init_alias(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, AliasVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, AliasVars);
 }
diff --git a/autocrypt/config.c b/autocrypt/config.c
index 4d761e4b..a720cb8f 100644
--- a/autocrypt/config.c
+++ b/autocrypt/config.c
@@ -65,7 +65,7 @@ bool config_init_autocrypt(struct ConfigSet *cs)
   bool rc = false;
 
 #if defined(USE_AUTOCRYPT)
-  rc |= cs_register_variables(cs, AutocryptVars, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, AutocryptVars);
 #endif
 
   return rc;
diff --git a/browser/config.c b/browser/config.c
index a63ce11a..d9c5de86 100644
--- a/browser/config.c
+++ b/browser/config.c
@@ -88,5 +88,5 @@ static struct ConfigDef BrowserVars[] = {
  */
 bool config_init_browser(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, BrowserVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, BrowserVars);
 }
diff --git a/compose/config.c b/compose/config.c
index 9c0cb2a2..363d66f9 100644
--- a/compose/config.c
+++ b/compose/config.c
@@ -67,5 +67,5 @@ static struct ConfigDef ComposeVars[] = {
  */
 bool config_init_compose(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, ComposeVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, ComposeVars);
 }
diff --git a/config/charset.h b/config/charset.h
index a972f086..0359f4cf 100644
--- a/config/charset.h
+++ b/config/charset.h
@@ -25,11 +25,6 @@
 
 #include <stdint.h>
 
-/* Note: To save space, sets of config variable flags are packed into a uint32_t.
- * When adding flags, check all config variables to ensure there are no overlaps of values */
-#define DT_CHARSET_SINGLE  (1 << 24) ///< Flag for charset_validator to allow only one charset
-#define DT_CHARSET_STRICT  (1 << 25) ///< Flag for charset_validator to use strict char check
-
 struct Buffer;
 struct ConfigDef;
 struct ConfigSet;
diff --git a/config/set.c b/config/set.c
index db33b466..7bee54ed 100644
--- a/config/set.c
+++ b/config/set.c
@@ -273,10 +273,9 @@ struct HashElem *cs_register_variable(const struct ConfigSet *cs,
  * cs_register_variables - Register a set of config items
  * @param cs    Config items
  * @param vars  Variable definition
- * @param flags Flags, e.g. #DT_DEPRECATED
  * @retval true All variables were registered successfully
  */
-bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], uint32_t flags)
+bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[])
 {
   if (!cs || !vars)
     return false;
@@ -287,7 +286,6 @@ bool cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[],
 
   for (size_t i = 0; vars[i].name; i++)
   {
-    vars[i].type |= flags;
     if (!cs_register_variable(cs, &vars[i], err))
     {
       mutt_debug(LL_DEBUG1, "%s\n", buf_string(err));
diff --git a/config/set.h b/config/set.h
index 38f3b244..56b8d475 100644
--- a/config/set.h
+++ b/config/set.h
@@ -63,7 +63,7 @@ struct ConfigSet;
 struct ConfigDef
 {
   const char   *name;      ///< User-visible name
-  uint32_t      type;      ///< Variable type, e.g. #DT_STRING
+  struct config_flags type; ///< Variable type and other flags
   intptr_t      initial;   ///< Initial value
   intptr_t      data;      ///< Extra variable data
 
@@ -263,7 +263,7 @@ const struct ConfigSetType *cs_get_type_def(const struct ConfigSet *cs, unsigned
 
 bool             cs_register_type     (struct ConfigSet *cs, const struct ConfigSetType *cst);
 struct HashElem *cs_register_variable (const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err);
-bool             cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[], uint32_t flags);
+bool             cs_register_variables(const struct ConfigSet *cs, struct ConfigDef vars[]);
 struct HashElem *cs_create_variable   (const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err);
 struct HashElem *cs_inherit_variable  (const struct ConfigSet *cs, struct HashElem *he_parent, const char *name);
 void             cs_uninherit_variable(const struct ConfigSet *cs, const char *name);
@@ -295,7 +295,7 @@ extern bool StartupComplete;
  */
 static inline bool startup_only(const struct ConfigDef *cdef, struct Buffer *err)
 {
-  if ((cdef->type & DT_ON_STARTUP) && StartupComplete)
+  if (cdef->type.on_startup && StartupComplete)
   {
     buf_printf(err, _("Option %s may only be set at startup"), cdef->name);
     return true;
diff --git a/config/sort2.h b/config/sort2.h
index 8eba89e0..ad31150f 100644
--- a/config/sort2.h
+++ b/config/sort2.h
@@ -27,12 +27,6 @@
 
 extern const struct Mapping SortMethods[];
 
-/* ... DT_SORT */
-/* Note: To save space, sets of config variable flags are packed into a uint32_t.
- * When adding flags, check all config variables to ensure there are no overlaps of values */
-#define DT_SORT_LAST    (1 << 21) ///< Sort flag for -last prefix
-#define DT_SORT_REVERSE (1 << 22) ///< Sort flag for -reverse prefix
-
 /**
  * enum SortType - Methods for sorting
  */
diff --git a/config/types.h b/config/types.h
index 2b64f78c..070d9c1f 100644
--- a/config/types.h
+++ b/config/types.h
@@ -25,62 +25,91 @@
 
 #include <stdint.h>
 
-/* Note: To save space, sets of config variable flags are packed into a uint32_t.
- * When adding flags, check all config variables to ensure there are no overlaps of values */
+enum config_type {
+	DT_ADDRESS,	///< e-mail address
+	DT_BOOL,	///< boolean option
+	DT_ENUM,	///< an enumeration
+	DT_HCACHE,	///< header cache backend
+	DT_LONG,	///< a number (long)
+	DT_MBTABLE,	///< multibyte char table
+	DT_NUMBER,	///< a number
+	DT_PATH,	///< a path to a file/directory
+	DT_QUAD,	///< quad-option (no/yes/ask-no/ask-yes)
+	DT_REGEX,	///< regular expressions
+	DT_SLIST,	///< a list of strings
+	DT_SORT,	///< sorting methods
+	DT_STRING,	///< a string
+	DT_SYNONYM,	///< synonym for another variable
+	DT_MYVAR,	///< a user-defined variable (my_foo)
+};
 
-/* Data Types */
-#define DT_ADDRESS   1  ///< e-mail address
-#define DT_BOOL      2  ///< boolean option
-#define DT_ENUM      3  ///< an enumeration
-#define DT_HCACHE    4  ///< header cache backend
-#define DT_LONG      5  ///< a number (long)
-#define DT_MBTABLE   6  ///< multibyte char table
-#define DT_NUMBER    7  ///< a number
-#define DT_PATH      8  ///< a path to a file/directory
-#define DT_QUAD      9  ///< quad-option (no/yes/ask-no/ask-yes)
-#define DT_REGEX    10  ///< regular expressions
-#define DT_SLIST    11  ///< a list of strings
-#define DT_SORT     12  ///< sorting methods
-#define DT_STRING   13  ///< a string
-#define DT_SYNONYM  14  ///< synonym for another variable
-#define DT_MYVAR    15  ///< a user-defined variable (my_foo)
+struct config_type_string {
+	bool mailbox : 1;	///< Don't perform path expansions
+	bool command : 1;	///< A command
+};
 
-#define DTYPE(x) ((x) & 0x1F)  ///< Mask for the Data Type
+struct config_type_integer {
+	bool not_negative : 1;	///< Negative numbers are not allowed
+};
 
-#define DT_NO_FLAGS            0   ///< No flags are set
+struct config_type_path {
+	bool dir : 1;	///< Path is a directory
+	bool file : 1;	///< Path is a file
+};
 
-#define DT_ON_STARTUP    (1 << 6)  ///< May only be set at startup
-#define DT_NOT_EMPTY     (1 << 7)  ///< Empty strings are not allowed
-#define DT_NOT_NEGATIVE  (1 << 8)  ///< Negative numbers are not allowed
-#define DT_MAILBOX       (1 << 9)  ///< Don't perform path expansions
-#define DT_SENSITIVE     (1 << 10) ///< Contains sensitive value, e.g. password
-#define DT_COMMAND       (1 << 11) ///< A command
-#define DT_INHERIT_ACC   (1 << 12) ///< Config item can be Account-specific
-#define DT_INHERIT_MBOX  (1 << 13) ///< Config item can be Mailbox-specific
-#define DT_PATH_DIR      (1 << 14) ///< Path is a directory
-#define DT_PATH_FILE     (1 << 15) ///< Path is a file
+struct config_type_regex {
+        bool match_case : 1;  ///< Case-sensitive matching
+        bool allow_not : 1;   ///< Regex can begin with '!'
+        bool nosub : 1;       ///< Do not report what was matched (REG_NOSUB)
+};
 
-#define IS_SENSITIVE(type) (((type) & DT_SENSITIVE) == DT_SENSITIVE)
-#define IS_MAILBOX(type)   (((type) & (DT_STRING | DT_MAILBOX)) == (DT_STRING | DT_MAILBOX))
-#define IS_COMMAND(type)   (((type) & (DT_STRING | DT_COMMAND)) == (DT_STRING | DT_COMMAND))
+struct config_type_slist {
+	bool sep_space : 1;	///< Slist items are space-separated
+	bool sep_comma : 1;	///< Slist items are comma-separated
+	bool sep_colon : 1;	///< Slist items are colon-separated
 
-/* subtypes for... */
-#define DT_SUBTYPE_MASK  0xFFC0  ///< Mask for the Data Subtype
+	bool allow_dupes : 1;	///< Slist may contain duplicates
+	bool allow_empty : 1;	///< Slist may be empty
+	bool case_sensitive : 1;	///< Slist is case-sensitive
+};
 
-typedef uint32_t ConfigRedrawFlags; ///< Flags for redraw/resort, e.g. #R_INDEX
-#define R_REDRAW_NO_FLAGS        0  ///< No refresh/resort flags
-#define R_INDEX           (1 << 17) ///< Redraw the index menu (MENU_INDEX)
-#define R_RESORT          (1 << 18) ///< Resort the mailbox
-#define R_RESORT_SUB      (1 << 19) ///< Resort subthreads
-#define R_RESORT_INIT     (1 << 20) ///< Resort from scratch
+struct config_type_sort {
+	bool last : 1;	///< Sort flag for -last prefix
+	bool reverse : 1;	///< Sort flag for -reverse prefix
+};
 
-#define R_REDRAW_MASK  0x01E0000    ///< Mask for the Redraw Flags
+struct config_flags {
+	enum config_type type : 4;
+	bool on_startup : 1;	///< May only be set at startup
+	bool not_empty : 1;	///< Empty strings are not allowed
+	bool sensitive : 1;	///< Contains sensitive value, e.g. password
+	struct {
+		bool single : 1;	///< Flag for charset_validator to allow only one charset
+		bool strict : 1;	///< Flag for charset_validator to use strict char check
+	} charset;
+	struct {
+		bool index : 1;		///< Redraw the index menu (MENU_INDEX)
+		bool resort : 1;	///< Resort the mailbox
+		bool resort_sub : 1;	///< Resort subthreads
+		bool resort_init : 1;	///< Resort from scratch
+	} redraw;
+	struct {
+		bool free_configdef: 1;	///< Config item must have its ConfigDef freed
+		bool deprecated: 1;	///< Config item shouldn't be used any more
+		bool inherited: 1;	///< Config item is inherited
+		bool initial_set: 1;	///< Config item must have its initial value freed
+	} internal;
+	union {
+		struct config_type_string string;
+		struct config_type_integer integer;
+		struct config_type_path path;
+		struct config_type_regex regex;
+		struct config_type_slist slist;
+		struct config_type_sort sort;
+	};
+};
 
-/* Private config item flags */
-#define DT_FREE_CONFIGDEF (1 << 26)  ///< Config item must have its ConfigDef freed
-#define DT_DEPRECATED     (1 << 27)  ///< Config item shouldn't be used any more
-#define DT_INHERITED      (1 << 28)  ///< Config item is inherited
-#define DT_INITIAL_SET    (1 << 29)  ///< Config item must have its initial value freed
-#define DT_DISABLED       (1 << 30)  ///< Config item is disabled
+#define IS_MAILBOX(flags)   ((flags).type == DT_STRING && (flags).string.mailbox)
+#define IS_COMMAND(flags)   ((flags).type == DT_STRING && (flags).string.command)
 
 #endif /* MUTT_CONFIG_TYPES_H */
diff --git a/conn/config.c b/conn/config.c
index 03091f8f..776c15e0 100644
--- a/conn/config.c
+++ b/conn/config.c
@@ -175,26 +175,26 @@ static struct ConfigDef ConnVarsGetaddr[] = {
  */
 bool config_init_conn(struct ConfigSet *cs)
 {
-  bool rc = cs_register_variables(cs, ConnVars, DT_NO_FLAGS);
+  bool rc = cs_register_variables(cs, ConnVars);
 
 #if defined(USE_SSL)
-  rc |= cs_register_variables(cs, ConnVarsSsl, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, ConnVarsSsl);
 #endif
 
 #if defined(USE_SSL_GNUTLS)
-  rc |= cs_register_variables(cs, ConnVarsGnutls, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, ConnVarsGnutls);
 #endif
 
 #if defined(USE_SSL_OPENSSL)
-  rc |= cs_register_variables(cs, ConnVarsOpenssl, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, ConnVarsOpenssl);
 #endif
 
 #if defined(HAVE_SSL_PARTIAL_CHAIN)
-  rc |= cs_register_variables(cs, ConnVarsPartial, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, ConnVarsPartial);
 #endif
 
 #if defined(HAVE_GETADDRINFO)
-  rc |= cs_register_variables(cs, ConnVarsGetaddr, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, ConnVarsGetaddr);
 #endif
 
   return rc;
diff --git a/hcache/config.c b/hcache/config.c
index 8693556f..a5998d98 100644
--- a/hcache/config.c
+++ b/hcache/config.c
@@ -183,19 +183,19 @@ bool config_init_hcache(struct ConfigSet *cs)
   bool rc = false;
 
 #if defined(USE_HCACHE)
-  rc |= cs_register_variables(cs, HcacheVars, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, HcacheVars);
 #endif
 
 #if defined(USE_HCACHE_COMPRESSION)
-  rc |= cs_register_variables(cs, HcacheVarsComp, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, HcacheVarsComp);
 #endif
 
 #if defined(HAVE_QDBM) || defined(HAVE_TC) || defined(HAVE_KC)
-  rc |= cs_register_variables(cs, HcacheVarsComp2, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, HcacheVarsComp2);
 #endif
 
 #if defined(HAVE_GDBM) || defined(HAVE_BDB)
-  rc |= cs_register_variables(cs, HcacheVarsPage, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, HcacheVarsPage);
 #endif
 
   return rc;
diff --git a/helpbar/config.c b/helpbar/config.c
index f673c607..9a448a22 100644
--- a/helpbar/config.c
+++ b/helpbar/config.c
@@ -48,5 +48,5 @@ static struct ConfigDef HelpbarVars[] = {
  */
 bool config_init_helpbar(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, HelpbarVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, HelpbarVars);
 }
diff --git a/history/config.c b/history/config.c
index 5aa243f6..637fd073 100644
--- a/history/config.c
+++ b/history/config.c
@@ -60,5 +60,5 @@ static struct ConfigDef HistoryVars[] = {
  */
 bool config_init_history(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, HistoryVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, HistoryVars);
 }
diff --git a/imap/config.c b/imap/config.c
index b785b1d2..24c9dd11 100644
--- a/imap/config.c
+++ b/imap/config.c
@@ -157,10 +157,10 @@ static struct ConfigDef ImapVarsZlib[] = {
  */
 bool config_init_imap(struct ConfigSet *cs)
 {
-  bool rc = cs_register_variables(cs, ImapVars, DT_NO_FLAGS);
+  bool rc = cs_register_variables(cs, ImapVars);
 
 #if defined(USE_ZLIB)
-  rc |= cs_register_variables(cs, ImapVarsZlib, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, ImapVarsZlib);
 #endif
 
   return rc;
diff --git a/index/config.c b/index/config.c
index c5625734..78b08f87 100644
--- a/index/config.c
+++ b/index/config.c
@@ -60,5 +60,5 @@ static struct ConfigDef IndexVars[] = {
  */
 bool config_init_index(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, IndexVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, IndexVars);
 }
diff --git a/init.c b/init.c
index 2977f31b..a546d54d 100644
--- a/init.c
+++ b/init.c
@@ -629,7 +629,7 @@ int mutt_query_variables(struct ListHead *queries, bool show_docs)
     struct HashElem *he = cs_subset_lookup(NeoMutt->sub, np->data);
     if (he)
     {
-      if (he->type & DT_DEPRECATED)
+      if (he->type.internal.deprecated)
       {
         mutt_warning(_("Option %s is deprecated"), np->data);
         rc = 1;
@@ -643,11 +643,10 @@ int mutt_query_variables(struct ListHead *queries, bool show_docs)
         continue;
       }
 
-      int type = DTYPE(he->type);
-      if (type == DT_PATH)
+      if (he->type.type == DT_PATH)
         mutt_pretty_mailbox(value.data, value.dsize);
 
-      if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD))
+      if ((he->type.type != DT_BOOL) && (he->type.type != DT_NUMBER) && (he->type.type != DT_LONG) && (he->type.type != DT_QUAD))
       {
         buf_reset(&tmp);
         pretty_var(value.data, &tmp);
diff --git a/maildir/config.c b/maildir/config.c
index 94b25c4f..63b14d16 100644
--- a/maildir/config.c
+++ b/maildir/config.c
@@ -103,10 +103,10 @@ static struct ConfigDef MaildirVarsHcache[] = {
  */
 bool config_init_maildir(struct ConfigSet *cs)
 {
-  bool rc = cs_register_variables(cs, MaildirVars, DT_NO_FLAGS);
+  bool rc = cs_register_variables(cs, MaildirVars);
 
 #if defined(USE_HCACHE)
-  rc |= cs_register_variables(cs, MaildirVarsHcache, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, MaildirVarsHcache);
 #endif
 
   return rc;
diff --git a/mbox/config.c b/mbox/config.c
index b7ae1c28..c5426ae1 100644
--- a/mbox/config.c
+++ b/mbox/config.c
@@ -48,5 +48,5 @@ static struct ConfigDef MboxVars[] = {
  */
 bool config_init_mbox(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, MboxVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, MboxVars);
 }
diff --git a/menu/config.c b/menu/config.c
index cf6975bc..4f17fe5e 100644
--- a/menu/config.c
+++ b/menu/config.c
@@ -54,5 +54,5 @@ static struct ConfigDef MenuVars[] = {
  */
 bool config_init_menu(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, MenuVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, MenuVars);
 }
diff --git a/mh/config.c b/mh/config.c
index 55631214..d70e9ceb 100644
--- a/mh/config.c
+++ b/mh/config.c
@@ -57,5 +57,5 @@ static struct ConfigDef MhVars[] = {
  */
 bool config_init_mh(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, MhVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, MhVars);
 }
diff --git a/mutt/hash.h b/mutt/hash.h
index dd88d1a0..1dbf7bbe 100644
--- a/mutt/hash.h
+++ b/mutt/hash.h
@@ -27,6 +27,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include "config/types.h"
 
 /**
  * union HashKey - The data item stored in a HashElem
@@ -42,7 +43,7 @@ union HashKey
  */
 struct HashElem
 {
-  int type;              ///< Type of data stored in Hash Table, e.g. #DT_STRING
+  struct config_flags type; ///< Type of data stored in Hash Table, e.g. #DT_STRING
   union HashKey key;     ///< Key representing the data
   void *data;            ///< User-supplied data
   struct HashElem *next; ///< Linked List
diff --git a/mutt/regex3.h b/mutt/regex3.h
index f67719a1..f7fa078f 100644
--- a/mutt/regex3.h
+++ b/mutt/regex3.h
@@ -31,13 +31,6 @@
 
 struct Buffer;
 
-/* ... DT_REGEX */
-/* Note: To save space, sets of config variable flags are packed into a uint32_t.
- * When adding flags, check all config variables to ensure there are no overlaps of values */
-#define DT_REGEX_MATCH_CASE (1 << 16)  ///< Case-sensitive matching
-#define DT_REGEX_ALLOW_NOT  (1 << 31)  ///< Regex can begin with '!'
-#define DT_REGEX_NOSUB      DT_NOT_NEGATIVE  ///< Do not report what was matched (REG_NOSUB)
-
 /* This is a non-standard option supported by Solaris 2.5.x
  * which allows patterns of the form \<...\> */
 #ifndef REG_WORDS
diff --git a/mutt/slist.h b/mutt/slist.h
index 67f5e827..b782bfa3 100644
--- a/mutt/slist.h
+++ b/mutt/slist.h
@@ -30,18 +30,6 @@
 
 struct Buffer;
 
-/* Note: To save space, sets of config variable flags are packed into a uint32_t.
- * When adding flags, check all config variables to ensure there are no overlaps of values */
-#define SLIST_SEP_SPACE (1 << 17)         ///< Slist items are space-separated
-#define SLIST_SEP_COMMA (1 << 18)         ///< Slist items are comma-separated
-#define SLIST_SEP_COLON (1 << 19)         ///< Slist items are colon-separated
-
-#define SLIST_SEP_MASK  0xE0000
-
-#define SLIST_ALLOW_DUPES    (1 << 21)    ///< Slist may contain duplicates
-#define SLIST_ALLOW_EMPTY    (1 << 22)    ///< Slist may be empty
-#define SLIST_CASE_SENSITIVE (1 << 23)    ///< Slist is case-sensitive
-
 /**
  * struct Slist - String list
  */
diff --git a/mutt_config.c b/mutt_config.c
index 70684f05..e2b303de 100644
--- a/mutt_config.c
+++ b/mutt_config.c
@@ -109,488 +109,491 @@ static int multipart_validator(const struct ConfigSet *cs, const struct ConfigDe
   return CSR_ERR_INVALID;
 }
 
+#define TP(t) .type = DT_##t
+#define IFL(f) .f = true
+#define FL(f) , .f = true
 /**
  * MainVars - General Config definitions for NeoMutt
  */
 static struct ConfigDef MainVars[] = {
   // clang-format off
-  { "abort_backspace", DT_BOOL, true, 0, NULL,
+  { "abort_backspace", {TP(BOOL)}, true, 0, NULL,
     "Hitting backspace against an empty prompt aborts the prompt"
   },
-  { "abort_key", DT_STRING|DT_NOT_EMPTY|DT_ON_STARTUP, IP "\007", 0, NULL,
+  { "abort_key", {TP(STRING) FL(on_startup) FL(not_empty)}, IP "\007", 0, NULL,
     "String representation of key to abort prompts"
   },
-  { "arrow_cursor", DT_BOOL, false, 0, NULL,
+  { "arrow_cursor", {TP(BOOL)}, false, 0, NULL,
     "Use an arrow '->' instead of highlighting in the index"
   },
-  { "arrow_string", DT_STRING|DT_NOT_EMPTY, IP "->", 0, NULL,
+  { "arrow_string", {TP(STRING) FL(not_empty)}, IP "->", 0, NULL,
     "Use an custom string for arrow_cursor"
   },
-  { "ascii_chars", DT_BOOL|R_INDEX, false, 0, NULL,
+  { "ascii_chars", {TP(BOOL) FL(redraw.index)}, false, 0, NULL,
     "Use plain ASCII characters, when drawing email threads"
   },
-  { "assumed_charset", DT_SLIST|SLIST_SEP_COLON|SLIST_ALLOW_EMPTY, 0, 0, charset_slist_validator,
+  { "assumed_charset", {TP(SLIST), .slist = {IFL(sep_colon) FL(allow_empty)}}, 0, 0, charset_slist_validator,
     "If a message is missing a character set, assume this character set"
   },
-  { "attach_format", DT_STRING|DT_NOT_EMPTY, IP "%u%D%I %t%4n %T%d %> [%.7m/%.10M, %.6e%<C?, %C>, %s] ", 0, NULL,
+  { "attach_format", {TP(STRING) FL(not_empty)}, IP "%u%D%I %t%4n %T%d %> [%.7m/%.10M, %.6e%<C?, %C>, %s] ", 0, NULL,
     "printf-like format string for the attachment menu"
   },
-  { "attach_save_dir", DT_PATH|DT_PATH_DIR, IP "./", 0, NULL,
+  { "attach_save_dir", {TP(PATH) FL(path.dir)}, IP "./", 0, NULL,
     "Default directory where attachments are saved"
   },
-  { "attach_save_without_prompting", DT_BOOL, false, 0, NULL,
+  { "attach_save_without_prompting", {TP(BOOL)}, false, 0, NULL,
     "If true, then don't prompt to save"
   },
-  { "attach_sep", DT_STRING, IP "\n", 0, NULL,
+  { "attach_sep", {TP(STRING)}, IP "\n", 0, NULL,
     "Separator to add between saved/printed/piped attachments"
   },
-  { "attach_split", DT_BOOL, true, 0, NULL,
+  { "attach_split", {TP(BOOL)}, true, 0, NULL,
     "Save/print/pipe tagged messages individually"
   },
-  { "auto_edit", DT_BOOL, false, 0, NULL,
+  { "auto_edit", {TP(BOOL)}, false, 0, NULL,
     "Skip the initial compose menu and edit the email"
   },
-  { "auto_subscribe", DT_BOOL, false, 0, NULL,
+  { "auto_subscribe", {TP(BOOL)}, false, 0, NULL,
     "Automatically check if the user is subscribed to a mailing list"
   },
-  { "auto_tag", DT_BOOL, false, 0, NULL,
+  { "auto_tag", {TP(BOOL)}, false, 0, NULL,
     "Automatically apply actions to all tagged messages"
   },
-  { "beep", DT_BOOL, true, 0, NULL,
+  { "beep", {TP(BOOL)}, true, 0, NULL,
     "Make a noise when an error occurs"
   },
-  { "beep_new", DT_BOOL, false, 0, NULL,
+  { "beep_new", {TP(BOOL)}, false, 0, NULL,
     "Make a noise when new mail arrives"
   },
-  { "bounce", DT_QUAD, MUTT_ASKYES, 0, NULL,
+  { "bounce", {TP(QUAD)}, MUTT_ASKYES, 0, NULL,
     "Confirm before bouncing a message"
   },
-  { "braille_friendly", DT_BOOL, false, 0, NULL,
+  { "braille_friendly", {TP(BOOL)}, false, 0, NULL,
     "Move the cursor to the beginning of the line"
   },
-  { "charset", DT_STRING|DT_NOT_EMPTY|DT_CHARSET_SINGLE, 0, 0, charset_validator,
+  { "charset", {TP(STRING) FL(not_empty) FL(charset.single)}, 0, 0, charset_validator,
     "Default character set for displaying text on screen"
   },
-  { "collapse_flagged", DT_BOOL, true, 0, NULL,
+  { "collapse_flagged", {TP(BOOL)}, true, 0, NULL,
     "Prevent the collapse of threads with flagged emails"
   },
-  { "collapse_unread", DT_BOOL, true, 0, NULL,
+  { "collapse_unread", {TP(BOOL)}, true, 0, NULL,
     "Prevent the collapse of threads with unread emails"
   },
-  { "color_directcolor", DT_BOOL|DT_ON_STARTUP, false, 0, NULL,
+  { "color_directcolor", {TP(BOOL) FL(on_startup)}, false, 0, NULL,
     "Use 24bit colors (aka truecolor aka directcolor)"
   },
-  { "config_charset", DT_STRING, 0, 0, charset_validator,
+  { "config_charset", {TP(STRING)}, 0, 0, charset_validator,
     "Character set that the config files are in"
   },
-  { "confirm_append", DT_BOOL, true, 0, NULL,
+  { "confirm_append", {TP(BOOL)}, true, 0, NULL,
     "Confirm before appending emails to a mailbox"
   },
-  { "confirm_create", DT_BOOL, true, 0, NULL,
+  { "confirm_create", {TP(BOOL)}, true, 0, NULL,
     "Confirm before creating a new mailbox"
   },
-  { "copy_decode_weed", DT_BOOL, false, 0, NULL,
+  { "copy_decode_weed", {TP(BOOL)}, false, 0, NULL,
     "Controls whether to weed headers when copying or saving emails"
   },
-  { "count_alternatives", DT_BOOL, false, 0, NULL,
+  { "count_alternatives", {TP(BOOL)}, false, 0, NULL,
     "Recurse inside multipart/alternatives while counting attachments"
   },
-  { "crypt_chars", DT_MBTABLE|R_INDEX, IP "SPsK ", 0, NULL,
+  { "crypt_chars", {TP(MBTABLE) FL(redraw.index)}, IP "SPsK ", 0, NULL,
     "User-configurable crypto flags: signed, encrypted etc."
   },
-  { "date_format", DT_STRING|DT_NOT_EMPTY, IP "!%a, %b %d, %Y at %I:%M:%S%p %Z", 0, NULL,
+  { "date_format", {TP(STRING) FL(not_empty)}, IP "!%a, %b %d, %Y at %I:%M:%S%p %Z", 0, NULL,
     "strftime format string for the `%d` expando"
   },
-  { "debug_file", DT_PATH|DT_PATH_FILE, IP "~/.neomuttdebug", 0, NULL,
+  { "debug_file", {TP(PATH) FL(path.file)}, IP "~/.neomuttdebug", 0, NULL,
     "File to save debug logs"
   },
-  { "debug_level", DT_NUMBER, 0, 0, level_validator,
+  { "debug_level", {TP(NUMBER)}, 0, 0, level_validator,
     "Logging level for debug logs"
   },
-  { "default_hook", DT_STRING, IP "~f %s !~P | (~P ~C %s)", 0, NULL,
+  { "default_hook", {TP(STRING)}, IP "~f %s !~P | (~P ~C %s)", 0, NULL,
     "Pattern to use for hooks that only have a simple regex"
   },
-  { "delete", DT_QUAD, MUTT_ASKYES, 0, NULL,
+  { "delete", {TP(QUAD)}, MUTT_ASKYES, 0, NULL,
     "Really delete messages, when the mailbox is closed"
   },
-  { "delete_untag", DT_BOOL, true, 0, NULL,
+  { "delete_untag", {TP(BOOL)}, true, 0, NULL,
     "Untag messages when they are marked for deletion"
   },
-  { "digest_collapse", DT_BOOL, true, 0, NULL,
+  { "digest_collapse", {TP(BOOL)}, true, 0, NULL,
     "Hide the subparts of a multipart/digest"
   },
-  { "duplicate_threads", DT_BOOL|R_RESORT|R_RESORT_INIT|R_INDEX, true, 0, NULL,
+  { "duplicate_threads", {TP(BOOL), .redraw = {IFL(index) FL(resort) FL(resort_init)}}, true, 0, NULL,
     "Highlight messages with duplicated message IDs"
   },
-  { "editor", DT_STRING|DT_NOT_EMPTY|DT_COMMAND, 0, 0, NULL,
+  { "editor", {TP(STRING) FL(string.command) FL(not_empty)}, 0, 0, NULL,
     "External command to use as an email editor"
   },
-  { "flag_chars", DT_MBTABLE|R_INDEX, IP "*!DdrONon- ", 0, NULL,
+  { "flag_chars", {TP(MBTABLE) FL(redraw.index)}, IP "*!DdrONon- ", 0, NULL,
     "User-configurable index flags: tagged, new, etc"
   },
-  { "flag_safe", DT_BOOL, false, 0, NULL,
+  { "flag_safe", {TP(BOOL)}, false, 0, NULL,
     "Protect flagged messages from deletion"
   },
-  { "folder", DT_STRING|DT_MAILBOX, IP "~/Mail", 0, NULL,
+  { "folder", {TP(STRING) FL(string.mailbox)}, IP "~/Mail", 0, NULL,
     "Base folder for a set of mailboxes"
   },
-  { "force_name", DT_BOOL, false, 0, NULL,
+  { "force_name", {TP(BOOL)}, false, 0, NULL,
     "Save outgoing mail in a folder of their name"
   },
-  { "forward_decode", DT_BOOL, true, 0, NULL,
+  { "forward_decode", {TP(BOOL)}, true, 0, NULL,
     "Decode the message when forwarding it"
   },
-  { "forward_quote", DT_BOOL, false, 0, NULL,
+  { "forward_quote", {TP(BOOL)}, false, 0, NULL,
     "Automatically quote a forwarded message using `$indent_string`"
   },
-  { "from", DT_ADDRESS, 0, 0, NULL,
+  { "from", {TP(ADDRESS)}, 0, 0, NULL,
     "Default 'From' address to use, if isn't otherwise set"
   },
-  { "from_chars", DT_MBTABLE|R_INDEX, 0, 0, NULL,
+  { "from_chars", {TP(MBTABLE) FL(redraw.index)}, 0, 0, NULL,
     "User-configurable index flags: to address, cc address, etc"
   },
-  { "gecos_mask", DT_REGEX, IP "^[^,]*", 0, NULL,
+  { "gecos_mask", {TP(REGEX)}, IP "^[^,]*", 0, NULL,
     "Regex for parsing GECOS field of /etc/passwd"
   },
-  { "header", DT_BOOL, false, 0, NULL,
+  { "header", {TP(BOOL)}, false, 0, NULL,
     "Include the message headers in the reply email (Weed applies)"
   },
-  { "hidden_tags", DT_SLIST|SLIST_SEP_COMMA, IP "unread,draft,flagged,passed,replied,attachment,signed,encrypted", 0, NULL,
+  { "hidden_tags", {TP(SLIST) FL(slist.sep_comma)}, IP "unread,draft,flagged,passed,replied,attachment,signed,encrypted", 0, NULL,
     "List of tags that shouldn't be displayed on screen (comma-separated)"
   },
-  { "hide_limited", DT_BOOL|R_INDEX, false, 0, NULL,
+  { "hide_limited", {TP(BOOL) FL(redraw.index)}, false, 0, NULL,
     "Don't indicate hidden messages, in the thread tree"
   },
-  { "hide_missing", DT_BOOL|R_INDEX, true, 0, NULL,
+  { "hide_missing", {TP(BOOL) FL(redraw.index)}, true, 0, NULL,
     "Don't indicate missing messages, in the thread tree"
   },
-  { "hide_thread_subject", DT_BOOL|R_INDEX, true, 0, NULL,
+  { "hide_thread_subject", {TP(BOOL) FL(redraw.index)}, true, 0, NULL,
     "Hide subjects that are similar to that of the parent message"
   },
-  { "hide_top_limited", DT_BOOL|R_INDEX, false, 0, NULL,
+  { "hide_top_limited", {TP(BOOL) FL(redraw.index)}, false, 0, NULL,
     "Don't indicate hidden top message, in the thread tree"
   },
-  { "hide_top_missing", DT_BOOL|R_INDEX, true, 0, NULL,
+  { "hide_top_missing", {TP(BOOL) FL(redraw.index)}, true, 0, NULL,
     "Don't indicate missing top message, in the thread tree"
   },
-  { "honor_disposition", DT_BOOL, false, 0, NULL,
+  { "honor_disposition", {TP(BOOL)}, false, 0, NULL,
     "Don't display MIME parts inline if they have a disposition of 'attachment'"
   },
-  { "hostname", DT_STRING, 0, 0, NULL,
+  { "hostname", {TP(STRING)}, 0, 0, NULL,
     "Fully-qualified domain name of this machine"
   },
-  { "implicit_auto_view", DT_BOOL, false, 0, NULL,
+  { "implicit_auto_view", {TP(BOOL)}, false, 0, NULL,
     "Display MIME attachments inline if a 'copiousoutput' mailcap entry exists"
   },
-  { "include_encrypted", DT_BOOL, false, 0, NULL,
+  { "include_encrypted", {TP(BOOL)}, false, 0, NULL,
     "Whether to include encrypted content when replying"
   },
-  { "include_only_first", DT_BOOL, false, 0, NULL,
+  { "include_only_first", {TP(BOOL)}, false, 0, NULL,
     "Only include the first attachment when replying"
   },
-  { "indent_string", DT_STRING, IP "> ", 0, NULL,
+  { "indent_string", {TP(STRING)}, IP "> ", 0, NULL,
     "String used to indent 'reply' text"
   },
-  { "index_format", DT_STRING|DT_NOT_EMPTY|R_INDEX, IP "%4C %Z %{%b %d} %-15.15L (%<l?%4l&%4c>) %s", 0, NULL,
+  { "index_format", {TP(STRING) FL(not_empty) FL(redraw.index)}, IP "%4C %Z %{%b %d} %-15.15L (%<l?%4l&%4c>) %s", 0, NULL,
     "printf-like format string for the index menu (emails)"
   },
-  { "keep_flagged", DT_BOOL, false, 0, NULL,
+  { "keep_flagged", {TP(BOOL)}, false, 0, NULL,
     "Don't move flagged messages from `$spool_file` to `$mbox`"
   },
-  { "local_date_header", DT_BOOL, true, 0, NULL,
+  { "local_date_header", {TP(BOOL)}, true, 0, NULL,
     "Convert the date in the Date header of sent emails into local timezone, UTC otherwise"
   },
-  { "mail_check", DT_NUMBER|DT_NOT_NEGATIVE, 5, 0, NULL,
+  { "mail_check", {TP(NUMBER) FL(integer.not_negative)}, 5, 0, NULL,
     "Number of seconds before NeoMutt checks for new mail"
   },
-  { "mail_check_recent", DT_BOOL, true, 0, NULL,
+  { "mail_check_recent", {TP(BOOL)}, true, 0, NULL,
     "Notify the user about new mail since the last time the mailbox was opened"
   },
-  { "mail_check_stats", DT_BOOL, false, 0, NULL,
+  { "mail_check_stats", {TP(BOOL)}, false, 0, NULL,
     "Periodically check for new mail"
   },
-  { "mail_check_stats_interval", DT_NUMBER|DT_NOT_NEGATIVE, 60, 0, NULL,
+  { "mail_check_stats_interval", {TP(NUMBER) FL(integer.not_negative)}, 60, 0, NULL,
     "How often to check for new mail"
   },
-  { "mailcap_path", DT_SLIST|SLIST_SEP_COLON, IP "~/.mailcap:" PKGDATADIR "/mailcap:" SYSCONFDIR "/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap", 0, NULL,
+  { "mailcap_path", {TP(SLIST) FL(slist.sep_colon)}, IP "~/.mailcap:" PKGDATADIR "/mailcap:" SYSCONFDIR "/mailcap:/etc/mailcap:/usr/etc/mailcap:/usr/local/etc/mailcap", 0, NULL,
     "List of mailcap files (colon-separated)"
   },
-  { "mailcap_sanitize", DT_BOOL, true, 0, NULL,
+  { "mailcap_sanitize", {TP(BOOL)}, true, 0, NULL,
     "Restrict the possible characters in mailcap expandos"
   },
-  { "mark_old", DT_BOOL|R_INDEX, true, 0, NULL,
+  { "mark_old", {TP(BOOL) FL(redraw.index)}, true, 0, NULL,
     "Mark new emails as old when leaving the mailbox"
   },
-  { "markers", DT_BOOL, true, 0, NULL,
+  { "markers", {TP(BOOL)}, true, 0, NULL,
     "Display a '+' at the beginning of wrapped lines in the pager"
   },
-  { "mbox", DT_STRING|DT_MAILBOX|R_INDEX, IP "~/mbox", 0, NULL,
+  { "mbox", {TP(STRING) FL(string.mailbox) FL(redraw.index)}, IP "~/mbox", 0, NULL,
     "Folder that receives read emails (see Move)"
   },
-  { "mbox_type", DT_ENUM, MUTT_MBOX, IP &MboxTypeDef, NULL,
+  { "mbox_type", {TP(ENUM)}, MUTT_MBOX, IP &MboxTypeDef, NULL,
     "Default type for creating new mailboxes"
   },
-  { "message_cache_clean", DT_BOOL, false, 0, NULL,
+  { "message_cache_clean", {TP(BOOL)}, false, 0, NULL,
     "(imap/pop) Clean out obsolete entries from the message cache"
   },
-  { "message_cache_dir", DT_PATH|DT_PATH_DIR, 0, 0, NULL,
+  { "message_cache_dir", {TP(PATH) FL(path.dir)}, 0, 0, NULL,
     "(imap/pop) Directory for the message cache"
   },
-  { "message_format", DT_STRING|DT_NOT_EMPTY, IP "%s", 0, NULL,
+  { "message_format", {TP(STRING) FL(not_empty)}, IP "%s", 0, NULL,
     "printf-like format string for listing attached messages"
   },
-  { "meta_key", DT_BOOL, false, 0, NULL,
+  { "meta_key", {TP(BOOL)}, false, 0, NULL,
     "Interpret 'ALT-x' as 'ESC-x'"
   },
-  { "mime_forward", DT_QUAD, MUTT_NO, 0, NULL,
+  { "mime_forward", {TP(QUAD)}, MUTT_NO, 0, NULL,
     "Forward a message as a 'message/RFC822' MIME part"
   },
-  { "mime_forward_rest", DT_QUAD, MUTT_YES, 0, NULL,
+  { "mime_forward_rest", {TP(QUAD)}, MUTT_YES, 0, NULL,
     "Forward all attachments, even if they can't be decoded"
   },
-  { "move", DT_QUAD, MUTT_NO, 0, NULL,
+  { "move", {TP(QUAD)}, MUTT_NO, 0, NULL,
     "Move emails from `$spool_file` to `$mbox` when read"
   },
-  { "narrow_tree", DT_BOOL|R_INDEX, false, 0, NULL,
+  { "narrow_tree", {TP(BOOL) FL(redraw.index)}, false, 0, NULL,
     "Draw a narrower thread tree in the index"
   },
-  { "net_inc", DT_NUMBER|DT_NOT_NEGATIVE, 10, 0, NULL,
+  { "net_inc", {TP(NUMBER) FL(integer.not_negative)}, 10, 0, NULL,
     "(socket) Update the progress bar after this many KB sent/received (0 to disable)"
   },
-  { "new_mail_command", DT_STRING|DT_COMMAND, 0, 0, NULL,
+  { "new_mail_command", {TP(STRING) FL(string.command)}, 0, 0, NULL,
     "External command to run when new mail arrives"
   },
-  { "pipe_decode", DT_BOOL, false, 0, NULL,
+  { "pipe_decode", {TP(BOOL)}, false, 0, NULL,
     "Decode the message when piping it"
   },
-  { "pipe_decode_weed", DT_BOOL, true, 0, NULL,
+  { "pipe_decode_weed", {TP(BOOL)}, true, 0, NULL,
     "Control whether to weed headers when piping an email"
   },
-  { "pipe_sep", DT_STRING, IP "\n", 0, NULL,
+  { "pipe_sep", {TP(STRING)}, IP "\n", 0, NULL,
     "Separator to add between multiple piped messages"
   },
-  { "pipe_split", DT_BOOL, false, 0, NULL,
+  { "pipe_split", {TP(BOOL)}, false, 0, NULL,
     "Run the pipe command on each message separately"
   },
-  { "postponed", DT_STRING|DT_MAILBOX|R_INDEX, IP "~/postponed", 0, NULL,
+  { "postponed", {TP(STRING) FL(string.mailbox) FL(redraw.index)}, IP "~/postponed", 0, NULL,
     "Folder to store postponed messages"
   },
-  { "preferred_languages", DT_SLIST|SLIST_SEP_COMMA, 0, 0, NULL,
+  { "preferred_languages", {TP(SLIST) FL(slist.sep_comma)}, 0, 0, NULL,
     "List of Preferred Languages for multilingual MIME (comma-separated)"
   },
-  { "print", DT_QUAD, MUTT_ASKNO, 0, NULL,
+  { "print", {TP(QUAD)}, MUTT_ASKNO, 0, NULL,
     "Confirm before printing a message"
   },
-  { "print_command", DT_STRING|DT_COMMAND, IP "lpr", 0, NULL,
+  { "print_command", {TP(STRING) FL(string.command)}, IP "lpr", 0, NULL,
     "External command to print a message"
   },
-  { "print_decode", DT_BOOL, true, 0, NULL,
+  { "print_decode", {TP(BOOL)}, true, 0, NULL,
     "Decode message before printing it"
   },
-  { "print_decode_weed", DT_BOOL, true, 0, NULL,
+  { "print_decode_weed", {TP(BOOL)}, true, 0, NULL,
     "Control whether to weed headers when printing an email"
   },
-  { "print_split", DT_BOOL, false, 0, NULL,
+  { "print_split", {TP(BOOL)}, false, 0, NULL,
     "Print multiple messages separately"
   },
-  { "quit", DT_QUAD, MUTT_YES, 0, NULL,
+  { "quit", {TP(QUAD)}, MUTT_YES, 0, NULL,
     "Prompt before exiting NeoMutt"
   },
-  { "quote_regex", DT_REGEX, IP "^([ \t]*[|>:}#])+", 0, NULL,
+  { "quote_regex", {TP(REGEX)}, IP "^([ \t]*[|>:}#])+", 0, NULL,
     "Regex to match quoted text in a reply"
   },
-  { "read_inc", DT_NUMBER|DT_NOT_NEGATIVE, 10, 0, NULL,
+  { "read_inc", {TP(NUMBER) FL(integer.not_negative)}, 10, 0, NULL,
     "Update the progress bar after this many records read (0 to disable)"
   },
-  { "read_only", DT_BOOL, false, 0, NULL,
+  { "read_only", {TP(BOOL)}, false, 0, NULL,
     "Open folders in read-only mode"
   },
-  { "real_name", DT_STRING|R_INDEX, 0, 0, NULL,
+  { "real_name", {TP(STRING) FL(redraw.index)}, 0, 0, NULL,
     "Real name of the user"
   },
-  { "record", DT_STRING|DT_MAILBOX, IP "~/sent", 0, NULL,
+  { "record", {TP(STRING) FL(string.mailbox)}, IP "~/sent", 0, NULL,
     "Folder to save 'sent' messages"
   },
-  { "reflow_space_quotes", DT_BOOL, true, 0, NULL,
+  { "reflow_space_quotes", {TP(BOOL)}, true, 0, NULL,
     "Insert spaces into reply quotes for 'format=flowed' messages"
   },
-  { "reflow_text", DT_BOOL, true, 0, NULL,
+  { "reflow_text", {TP(BOOL)}, true, 0, NULL,
     "Reformat paragraphs of 'format=flowed' text"
   },
-  { "reflow_wrap", DT_NUMBER, 78, 0, NULL,
+  { "reflow_wrap", {TP(NUMBER)}, 78, 0, NULL,
     "Maximum paragraph width for reformatting 'format=flowed' text"
   },
-  { "reply_regex", DT_REGEX|R_INDEX|R_RESORT, IP "^((re|aw|sv)(\\[[0-9]+\\])*:[ \t]*)*", 0, NULL,
+  { "reply_regex", {TP(REGEX), .redraw = {IFL(index) FL(resort)}}, IP "^((re|aw|sv)(\\[[0-9]+\\])*:[ \t]*)*", 0, NULL,
     "Regex to match message reply subjects like 're: '"
   },
-  { "resolve", DT_BOOL, true, 0, NULL,
+  { "resolve", {TP(BOOL)}, true, 0, NULL,
     "Move to the next email whenever a command modifies an email"
   },
-  { "resume_edited_draft_files", DT_BOOL, true, 0, NULL,
+  { "resume_edited_draft_files", {TP(BOOL)}, true, 0, NULL,
     "Resume editing previously saved draft files"
   },
-  { "reverse_alias", DT_BOOL|R_INDEX, false, 0, NULL,
+  { "reverse_alias", {TP(BOOL) FL(redraw.index)}, false, 0, NULL,
     "Display the alias in the index, rather than the message's sender"
   },
-  { "rfc2047_parameters", DT_BOOL, true, 0, NULL,
+  { "rfc2047_parameters", {TP(BOOL)}, true, 0, NULL,
     "Decode RFC2047-encoded MIME parameters"
   },
-  { "save_address", DT_BOOL, false, 0, NULL,
+  { "save_address", {TP(BOOL)}, false, 0, NULL,
     "Use sender's full address as a default save folder"
   },
-  { "save_empty", DT_BOOL, true, 0, NULL,
+  { "save_empty", {TP(BOOL)}, true, 0, NULL,
     "(mbox,mmdf) Preserve empty mailboxes"
   },
-  { "save_name", DT_BOOL, false, 0, NULL,
+  { "save_name", {TP(BOOL)}, false, 0, NULL,
     "Save outgoing message to mailbox of recipient's name if it exists"
   },
-  { "score", DT_BOOL, true, 0, NULL,
+  { "score", {TP(BOOL)}, true, 0, NULL,
     "Use message scoring"
   },
-  { "score_threshold_delete", DT_NUMBER, -1, 0, NULL,
+  { "score_threshold_delete", {TP(NUMBER)}, -1, 0, NULL,
     "Messages with a lower score will be automatically deleted"
   },
-  { "score_threshold_flag", DT_NUMBER, 9999, 0, NULL,
+  { "score_threshold_flag", {TP(NUMBER)}, 9999, 0, NULL,
     "Messages with a greater score will be automatically flagged"
   },
-  { "score_threshold_read", DT_NUMBER, -1, 0, NULL,
+  { "score_threshold_read", {TP(NUMBER)}, -1, 0, NULL,
     "Messages with a lower score will be automatically marked read"
   },
-  { "send_charset", DT_SLIST|SLIST_SEP_COLON|SLIST_ALLOW_EMPTY|DT_CHARSET_STRICT, IP "us-ascii:iso-8859-1:utf-8", 0, charset_slist_validator,
+  { "send_charset", {TP(SLIST) FL(charset.strict), .slist = {IFL(sep_colon) FL(allow_empty)}}, IP "us-ascii:iso-8859-1:utf-8", 0, charset_slist_validator,
     "Character sets for outgoing mail"
   },
-  { "shell", DT_STRING|DT_COMMAND, IP "/bin/sh", 0, NULL,
+  { "shell", {TP(STRING) FL(string.command)}, IP "/bin/sh", 0, NULL,
     "External command to run subshells in"
   },
-  { "show_multipart_alternative", DT_STRING, 0, 0, multipart_validator,
+  { "show_multipart_alternative", {TP(STRING)}, 0, 0, multipart_validator,
     "How to display 'multipart/alternative' MIME parts"
   },
-  { "simple_search", DT_STRING, IP "~f %s | ~s %s", 0, NULL,
+  { "simple_search", {TP(STRING)}, IP "~f %s | ~s %s", 0, NULL,
     "Pattern to search for when search doesn't contain ~'s"
   },
-  { "size_show_bytes", DT_BOOL, false, 0, NULL,
+  { "size_show_bytes", {TP(BOOL)}, false, 0, NULL,
     "Show smaller sizes in bytes"
   },
-  { "size_show_fractions", DT_BOOL, true, 0, NULL,
+  { "size_show_fractions", {TP(BOOL)}, true, 0, NULL,
     "Show size fractions with a single decimal place"
   },
-  { "size_show_mb", DT_BOOL, true, 0, NULL,
+  { "size_show_mb", {TP(BOOL)}, true, 0, NULL,
     "Show sizes in megabytes for sizes greater than 1 megabyte"
   },
-  { "size_units_on_left", DT_BOOL, false, 0, NULL,
+  { "size_units_on_left", {TP(BOOL)}, false, 0, NULL,
     "Show the units as a prefix to the size"
   },
-  { "sleep_time", DT_NUMBER|DT_NOT_NEGATIVE, 1, 0, NULL,
+  { "sleep_time", {TP(NUMBER) FL(integer.not_negative)}, 1, 0, NULL,
     "Time to pause after certain info messages"
   },
-  { "sort", DT_SORT|DT_SORT_REVERSE|DT_SORT_LAST|R_INDEX|R_RESORT, SORT_DATE, IP SortMethods, sort_validator,
+  { "sort", {TP(SORT), .sort = {IFL(reverse) FL(last)}, .redraw = {IFL(index) FL(resort)}}, SORT_DATE, IP SortMethods, sort_validator,
     "Sort method for the index"
   },
-  { "sort_aux", DT_SORT|DT_SORT_REVERSE|DT_SORT_LAST|R_INDEX|R_RESORT|R_RESORT_SUB, SORT_DATE, IP SortAuxMethods, NULL,
+  { "sort_aux", {TP(SORT), .sort = {IFL(reverse) FL(last)}, .redraw = {IFL(index) FL(resort) FL(resort_sub)}}, SORT_DATE, IP SortAuxMethods, NULL,
     "Secondary sort method for the index"
   },
-  { "sort_re", DT_BOOL|R_INDEX|R_RESORT|R_RESORT_INIT, true, 0, NULL,
+  { "sort_re", {TP(BOOL), .redraw = {IFL(index) FL(resort) FL(resort_init)}}, true, 0, NULL,
     "Whether $reply_regex must be matched when not $strict_threads"
   },
-  { "spam_separator", DT_STRING, IP ",", 0, NULL,
+  { "spam_separator", {TP(STRING)}, IP ",", 0, NULL,
     "Separator for multiple spam headers"
   },
-  { "spool_file", DT_STRING|DT_MAILBOX, 0, 0, NULL,
+  { "spool_file", {TP(STRING) FL(string.mailbox)}, 0, 0, NULL,
     "Inbox"
   },
-  { "status_chars", DT_MBTABLE|R_INDEX, IP "-*%A", 0, NULL,
+  { "status_chars", {TP(MBTABLE) FL(redraw.index)}, IP "-*%A", 0, NULL,
     "Indicator characters for the status bar"
   },
-  { "status_format", DT_STRING|R_INDEX, IP "-%r-NeoMutt: %D [Msgs:%<M?%M/>%m%<n? New:%n>%<o? Old:%o>%<d? Del:%d>%<F? Flag:%F>%<t? Tag:%t>%<p? Post:%p>%<b? Inc:%b>%<l? %l>]---(%<T?%T/>%s/%S)-%>-(%P)---", 0, NULL,
+  { "status_format", {TP(STRING) FL(redraw.index)}, IP "-%r-NeoMutt: %D [Msgs:%<M?%M/>%m%<n? New:%n>%<o? Old:%o>%<d? Del:%d>%<F? Flag:%F>%<t? Tag:%t>%<p? Post:%p>%<b? Inc:%b>%<l? %l>]---(%<T?%T/>%s/%S)-%>-(%P)---", 0, NULL,
     "printf-like format string for the index's status line"
   },
-  { "status_on_top", DT_BOOL, false, 0, NULL,
+  { "status_on_top", {TP(BOOL)}, false, 0, NULL,
     "Display the status bar at the top"
   },
-  { "strict_threads", DT_BOOL|R_RESORT|R_RESORT_INIT|R_INDEX, false, 0, NULL,
+  { "strict_threads", {TP(BOOL), .redraw = {IFL(resort) FL(resort_init) FL(index)}}, false, 0, NULL,
     "Thread messages using 'In-Reply-To' and 'References' headers"
   },
-  { "suspend", DT_BOOL, true, 0, NULL,
+  { "suspend", {TP(BOOL)}, true, 0, NULL,
     "Allow the user to suspend NeoMutt using '^Z'"
   },
-  { "text_flowed", DT_BOOL, false, 0, NULL,
+  { "text_flowed", {TP(BOOL)}, false, 0, NULL,
     "Generate 'format=flowed' messages"
   },
-  { "thread_received", DT_BOOL|R_RESORT|R_RESORT_INIT|R_INDEX, false, 0, NULL,
+  { "thread_received", {TP(BOOL), .redraw = {IFL(resort) FL(resort_init) FL(index)}}, false, 0, NULL,
     "Sort threaded messages by their received date"
   },
-  { "time_inc", DT_NUMBER|DT_NOT_NEGATIVE, 0, 0, NULL,
+  { "time_inc", {TP(NUMBER) FL(integer.not_negative)}, 0, 0, NULL,
     "Frequency of progress bar updates (milliseconds)"
   },
-  { "timeout", DT_NUMBER|DT_NOT_NEGATIVE, 600, 0, NULL,
+  { "timeout", {TP(NUMBER) FL(integer.not_negative)}, 600, 0, NULL,
     "Time to wait for user input in menus"
   },
-  { "tmp_dir", DT_PATH|DT_PATH_DIR|DT_NOT_EMPTY, IP TMPDIR, 0, NULL,
+  { "tmp_dir", {TP(PATH) FL(path.dir) FL(not_empty)}, IP TMPDIR, 0, NULL,
     "Directory for temporary files"
   },
-  { "to_chars", DT_MBTABLE|R_INDEX, IP " +TCFLR", 0, NULL,
+  { "to_chars", {TP(MBTABLE) FL(redraw.index)}, IP " +TCFLR", 0, NULL,
     "Indicator characters for the 'To' field in the index"
   },
-  { "trash", DT_STRING|DT_MAILBOX, 0, 0, NULL,
+  { "trash", {TP(STRING) FL(string.mailbox)}, 0, 0, NULL,
     "Folder to put deleted emails"
   },
-  { "ts_enabled", DT_BOOL|R_INDEX, false, 0, NULL,
+  { "ts_enabled", {TP(BOOL) FL(redraw.index)}, false, 0, NULL,
     "Allow NeoMutt to set the terminal status line and icon"
   },
-  { "ts_icon_format", DT_STRING|R_INDEX, IP "M%<n?AIL&ail>", 0, NULL,
+  { "ts_icon_format", {TP(STRING) FL(redraw.index)}, IP "M%<n?AIL&ail>", 0, NULL,
     "printf-like format string for the terminal's icon title"
   },
-  { "ts_status_format", DT_STRING|R_INDEX, IP "NeoMutt with %<m?%m messages&no messages>%<n? [%n NEW]>", 0, NULL,
+  { "ts_status_format", {TP(STRING) FL(redraw.index)}, IP "NeoMutt with %<m?%m messages&no messages>%<n? [%n NEW]>", 0, NULL,
     "printf-like format string for the terminal's status (window title)"
   },
-  { "use_domain", DT_BOOL, true, 0, NULL,
+  { "use_domain", {TP(BOOL)}, true, 0, NULL,
     "Qualify local addresses using this domain"
   },
-  { "use_threads", DT_ENUM|R_INDEX|R_RESORT, UT_UNSET, IP &UseThreadsTypeDef, NULL,
+  { "use_threads", {TP(ENUM), .redraw = {IFL(index) FL(resort)}}, UT_UNSET, IP &UseThreadsTypeDef, NULL,
     "Whether to use threads for the index"
   },
-  { "wait_key", DT_BOOL, true, 0, NULL,
+  { "wait_key", {TP(BOOL)}, true, 0, NULL,
     "Prompt to press a key after running external commands"
   },
-  { "weed", DT_BOOL, true, 0, NULL,
+  { "weed", {TP(BOOL)}, true, 0, NULL,
     "Filter headers when displaying/forwarding/printing/replying"
   },
-  { "wrap", DT_NUMBER, 0, 0, NULL,
+  { "wrap", {TP(NUMBER)}, 0, 0, NULL,
     "Width to wrap text in the pager"
   },
-  { "wrap_search", DT_BOOL, true, 0, NULL,
+  { "wrap_search", {TP(BOOL)}, true, 0, NULL,
     "Wrap around when the search hits the end"
   },
-  { "write_inc", DT_NUMBER|DT_NOT_NEGATIVE, 10, 0, NULL,
+  { "write_inc", {TP(NUMBER) FL(integer.not_negative)}, 10, 0, NULL,
     "Update the progress bar after this many records written (0 to disable)"
   },
 
-  { "escape",                    DT_DEPRECATED|DT_STRING, 0, IP "2021-03-18" },
-  { "ignore_linear_white_space", DT_DEPRECATED|DT_BOOL,   0, IP "2021-03-18" },
-  { "visual",                    DT_DEPRECATED|DT_STRING, 0, IP "2021-03-18" },
+  { "escape",                    {TP(STRING) FL(internal.deprecated)}, 0, IP "2021-03-18" },
+  { "ignore_linear_white_space", {TP(BOOL) FL(internal.deprecated)},   0, IP "2021-03-18" },
+  { "visual",                    {TP(STRING) FL(internal.deprecated)}, 0, IP "2021-03-18" },
 
-  { "autoedit",                  DT_SYNONYM, IP "auto_edit",                  IP "2021-03-21" },
-  { "confirmappend",             DT_SYNONYM, IP "confirm_append",             IP "2021-03-21" },
-  { "confirmcreate",             DT_SYNONYM, IP "confirm_create",             IP "2021-03-21" },
-  { "edit_hdrs",                 DT_SYNONYM, IP "edit_headers",               IP "2021-03-21" },
-  { "forw_decode",               DT_SYNONYM, IP "forward_decode",             IP "2021-03-21" },
-  { "forw_quote",                DT_SYNONYM, IP "forward_quote",              IP "2021-03-21" },
-  { "hdr_format",                DT_SYNONYM, IP "index_format",               IP "2021-03-21" },
-  { "implicit_autoview",         DT_SYNONYM, IP "implicit_auto_view",         IP "2023-01-25" },
-  { "include_onlyfirst",         DT_SYNONYM, IP "include_only_first",         IP "2021-03-21" },
-  { "indent_str",                DT_SYNONYM, IP "indent_string",              IP "2021-03-21" },
-  { "message_cachedir",          DT_SYNONYM, IP "message_cache_dir",          IP "2023-01-25" },
-  { "mime_fwd",                  DT_SYNONYM, IP "mime_forward",               IP "2021-03-21" },
-  { "msg_format",                DT_SYNONYM, IP "message_format",             IP "2021-03-21" },
-  { "print_cmd",                 DT_SYNONYM, IP "print_command",              IP "2021-03-21" },
-  { "quote_regexp",              DT_SYNONYM, IP "quote_regex",                IP "2021-03-21" },
-  { "realname",                  DT_SYNONYM, IP "real_name",                  IP "2021-03-21" },
-  { "reply_regexp",              DT_SYNONYM, IP "reply_regex",                IP "2021-03-21" },
-  { "spoolfile",                 DT_SYNONYM, IP "spool_file",                 IP "2021-03-21" },
-  { "tmpdir",                    DT_SYNONYM, IP "tmp_dir",                    IP "2023-01-25" },
-  { "xterm_icon",                DT_SYNONYM, IP "ts_icon_format",             IP "2021-03-21" },
-  { "xterm_set_titles",          DT_SYNONYM, IP "ts_enabled",                 IP "2021-03-21" },
-  { "xterm_title",               DT_SYNONYM, IP "ts_status_format",           IP "2021-03-21" },
+  { "autoedit",                  {TP(SYNONYM)}, IP "auto_edit",                  IP "2021-03-21" },
+  { "confirmappend",             {TP(SYNONYM)}, IP "confirm_append",             IP "2021-03-21" },
+  { "confirmcreate",             {TP(SYNONYM)}, IP "confirm_create",             IP "2021-03-21" },
+  { "edit_hdrs",                 {TP(SYNONYM)}, IP "edit_headers",               IP "2021-03-21" },
+  { "forw_decode",               {TP(SYNONYM)}, IP "forward_decode",             IP "2021-03-21" },
+  { "forw_quote",                {TP(SYNONYM)}, IP "forward_quote",              IP "2021-03-21" },
+  { "hdr_format",                {TP(SYNONYM)}, IP "index_format",               IP "2021-03-21" },
+  { "implicit_autoview",         {TP(SYNONYM)}, IP "implicit_auto_view",         IP "2023-01-25" },
+  { "include_onlyfirst",         {TP(SYNONYM)}, IP "include_only_first",         IP "2021-03-21" },
+  { "indent_str",                {TP(SYNONYM)}, IP "indent_string",              IP "2021-03-21" },
+  { "message_cachedir",          {TP(SYNONYM)}, IP "message_cache_dir",          IP "2023-01-25" },
+  { "mime_fwd",                  {TP(SYNONYM)}, IP "mime_forward",               IP "2021-03-21" },
+  { "msg_format",                {TP(SYNONYM)}, IP "message_format",             IP "2021-03-21" },
+  { "print_cmd",                 {TP(SYNONYM)}, IP "print_command",              IP "2021-03-21" },
+  { "quote_regexp",              {TP(SYNONYM)}, IP "quote_regex",                IP "2021-03-21" },
+  { "realname",                  {TP(SYNONYM)}, IP "real_name",                  IP "2021-03-21" },
+  { "reply_regexp",              {TP(SYNONYM)}, IP "reply_regex",                IP "2021-03-21" },
+  { "spoolfile",                 {TP(SYNONYM)}, IP "spool_file",                 IP "2021-03-21" },
+  { "tmpdir",                    {TP(SYNONYM)}, IP "tmp_dir",                    IP "2023-01-25" },
+  { "xterm_icon",                {TP(SYNONYM)}, IP "ts_icon_format",             IP "2021-03-21" },
+  { "xterm_set_titles",          {TP(SYNONYM)}, IP "ts_enabled",                 IP "2021-03-21" },
+  { "xterm_title",               {TP(SYNONYM)}, IP "ts_status_format",           IP "2021-03-21" },
 
   { NULL },
   // clang-format on
@@ -607,10 +610,10 @@ static struct ConfigDef MainVars[] = {
  */
 static struct ConfigDef MainVarsMixmaster[] = {
   // clang-format off
-  { "mix_entry_format", DT_STRING|DT_NOT_EMPTY, IP "%4n %c %-16s %a", 0, NULL,
+  { "mix_entry_format", {TP(STRING) FL(not_empty)}, IP "%4n %c %-16s %a", 0, NULL,
     "(mixmaster) printf-like format string for the mixmaster chain"
   },
-  { "mixmaster", DT_STRING|DT_COMMAND, IP MIXMASTER_DEFAULT, 0, NULL,
+  { "mixmaster", {TP(STRING) FL(string.command)}, IP MIXMASTER_DEFAULT, 0, NULL,
     "(mixmaster) External command to route a mixmaster message"
   },
   { NULL },
@@ -624,10 +627,10 @@ static struct ConfigDef MainVarsMixmaster[] = {
  */
 static struct ConfigDef MainVarsIdn[] = {
   // clang-format off
-  { "idn_decode", DT_BOOL, true, 0, NULL,
+  { "idn_decode", {TP(BOOL)}, true, 0, NULL,
     "(idn) Decode international domain names"
   },
-  { "idn_encode", DT_BOOL, true, 0, NULL,
+  { "idn_encode", {TP(BOOL)}, true, 0, NULL,
     "(idn) Encode international domain names"
   },
   { NULL },
@@ -640,14 +643,14 @@ static struct ConfigDef MainVarsIdn[] = {
  */
 static bool config_init_main(struct ConfigSet *cs)
 {
-  bool rc = cs_register_variables(cs, MainVars, DT_NO_FLAGS);
+  bool rc = cs_register_variables(cs, MainVars);
 
 #if defined(MIXMASTER)
-  rc |= cs_register_variables(cs, MainVarsMixmaster, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, MainVarsMixmaster);
 #endif
 
 #if defined(HAVE_LIBIDN)
-  rc |= cs_register_variables(cs, MainVarsIdn, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, MainVarsIdn);
 #endif
 
   return rc;
diff --git a/ncrypt/config.c b/ncrypt/config.c
index e914b1bd..a172f0c1 100644
--- a/ncrypt/config.c
+++ b/ncrypt/config.c
@@ -303,18 +303,18 @@ static struct ConfigDef NcryptVarsSmime[] = {
  */
 bool config_init_ncrypt(struct ConfigSet *cs)
 {
-  bool rc = cs_register_variables(cs, NcryptVars, DT_NO_FLAGS);
+  bool rc = cs_register_variables(cs, NcryptVars);
 
 #if defined(CRYPT_BACKEND_GPGME)
-  rc |= cs_register_variables(cs, NcryptVarsGpgme, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, NcryptVarsGpgme);
 #endif
 
 #if defined(CRYPT_BACKEND_CLASSIC_PGP)
-  rc |= cs_register_variables(cs, NcryptVarsPgp, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, NcryptVarsPgp);
 #endif
 
 #if defined(CRYPT_BACKEND_CLASSIC_SMIME)
-  rc |= cs_register_variables(cs, NcryptVarsSmime, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, NcryptVarsSmime);
 #endif
 
   return rc;
diff --git a/nntp/config.c b/nntp/config.c
index ae4c4bf9..c9af2029 100644
--- a/nntp/config.c
+++ b/nntp/config.c
@@ -96,5 +96,5 @@ static struct ConfigDef NntpVars[] = {
  */
 bool config_init_nntp(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, NntpVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, NntpVars);
 }
diff --git a/notmuch/config.c b/notmuch/config.c
index 71ab3b19..951d1bc3 100644
--- a/notmuch/config.c
+++ b/notmuch/config.c
@@ -174,7 +174,7 @@ bool config_init_notmuch(struct ConfigSet *cs)
   bool rc = false;
 
 #if defined(USE_NOTMUCH)
-  rc |= cs_register_variables(cs, NotmuchVars, DT_NO_FLAGS);
+  rc |= cs_register_variables(cs, NotmuchVars);
 #endif
 
   return rc;
diff --git a/pager/config.c b/pager/config.c
index b9be8dc1..fe28b513 100644
--- a/pager/config.c
+++ b/pager/config.c
@@ -114,5 +114,5 @@ const char *pager_get_pager(struct ConfigSubset *sub)
  */
 bool config_init_pager(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, PagerVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, PagerVars);
 }
diff --git a/pattern/config.c b/pattern/config.c
index 21047c11..a9ea8c5f 100644
--- a/pattern/config.c
+++ b/pattern/config.c
@@ -54,5 +54,5 @@ static struct ConfigDef PatternVars[] = {
  */
 bool config_init_pattern(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, PatternVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, PatternVars);
 }
diff --git a/pop/config.c b/pop/config.c
index ebe57b39..a4ca0727 100644
--- a/pop/config.c
+++ b/pop/config.c
@@ -107,5 +107,5 @@ static struct ConfigDef PopVars[] = {
  */
 bool config_init_pop(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, PopVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, PopVars);
 }
diff --git a/send/config.c b/send/config.c
index 8a3cd45f..50d4bff9 100644
--- a/send/config.c
+++ b/send/config.c
@@ -375,5 +375,5 @@ static struct ConfigDef SendVars[] = {
  */
 bool config_init_send(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, SendVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, SendVars);
 }
diff --git a/sidebar/config.c b/sidebar/config.c
index eb8b33f0..b538c8a8 100644
--- a/sidebar/config.c
+++ b/sidebar/config.c
@@ -107,5 +107,5 @@ static struct ConfigDef SidebarVars[] = {
  */
 bool config_init_sidebar(struct ConfigSet *cs)
 {
-  return cs_register_variables(cs, SidebarVars, DT_NO_FLAGS);
+  return cs_register_variables(cs, SidebarVars);
 }
diff --git a/test/account/account_mailbox_add.c b/test/account/account_mailbox_add.c
index 903f6b7d..d01ac32a 100644
--- a/test/account/account_mailbox_add.c
+++ b/test/account/account_mailbox_add.c
@@ -44,7 +44,7 @@ void test_account_mailbox_add(void)
     TEST_CHECK(account_mailbox_add(NULL, NULL) == false);
   }
 
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   {
     struct ConfigSubset *sub = cs_subset_new("account", NULL, NULL);
diff --git a/test/account/account_mailbox_remove.c b/test/account/account_mailbox_remove.c
index a232f391..1a148873 100644
--- a/test/account/account_mailbox_remove.c
+++ b/test/account/account_mailbox_remove.c
@@ -45,7 +45,7 @@ void test_account_mailbox_remove(void)
   }
 
   {
-    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
     struct ConfigSubset *sub = cs_subset_new("account", NULL, NULL);
     struct Account *a = account_new("dummy", sub);
diff --git a/test/account/account_new.c b/test/account/account_new.c
index 2b20679a..fca78fe8 100644
--- a/test/account/account_new.c
+++ b/test/account/account_new.c
@@ -45,7 +45,7 @@ void test_account_new(void)
   }
 
   {
-    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
     struct ConfigSubset *sub = cs_subset_new("account", NULL, NULL);
     struct Account *a = account_new("dummy", sub);
diff --git a/test/address/config_type.c b/test/address/config_type.c
index c4052cd8..f779062d 100644
--- a/test/address/config_type.c
+++ b/test/address/config_type.c
@@ -611,7 +611,7 @@ void test_address_config(void)
   struct ConfigSet *cs = sub->cs;
 
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
 
diff --git a/test/address/mutt_addr_for_display.c b/test/address/mutt_addr_for_display.c
index d3bbd785..97803c17 100644
--- a/test/address/mutt_addr_for_display.c
+++ b/test/address/mutt_addr_for_display.c
@@ -58,7 +58,7 @@ void test_mutt_addr_for_display(void)
       .intl_checked = 0,
     };
 
-    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
     const char *expected = "bob at bobsdomain";
     const char *actual = mutt_addr_for_display(&addr);
diff --git a/test/address/mutt_addrlist_to_intl.c b/test/address/mutt_addrlist_to_intl.c
index 17f73602..42213caf 100644
--- a/test/address/mutt_addrlist_to_intl.c
+++ b/test/address/mutt_addrlist_to_intl.c
@@ -64,7 +64,7 @@ void test_mutt_addrlist_to_intl(void)
                          .intl = "test at xn--nixierhre-57a.nixieclock-tube.com" },
                        { .local = "test@வலைப்பூ.com", .intl = "test at xn--xlcawl2e7azb.com" } };
 
-    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
     cs_subset_str_string_set(NeoMutt->sub, "charset", "utf-8", NULL);
 #ifdef HAVE_LIBIDN
diff --git a/test/address/mutt_addrlist_write_list.c b/test/address/mutt_addrlist_write_list.c
index bd759296..281bbb65 100644
--- a/test/address/mutt_addrlist_write_list.c
+++ b/test/address/mutt_addrlist_write_list.c
@@ -38,7 +38,7 @@ static struct ConfigDef Vars[] = {
 void test_mutt_addrlist_write_list(void)
 {
   {
-    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+    TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
     struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
     const char in[] = "some-group: first at example.com,second at example.com; John Doe <john at doe.org>, \"Foo J. Bar\" <foo-j-bar at baz.com>";
     mutt_addrlist_parse(&al, in);
diff --git a/test/color/ansi.c b/test/color/ansi.c
index 2b47c7aa..7f1d07f2 100644
--- a/test/color/ansi.c
+++ b/test/color/ansi.c
@@ -42,7 +42,7 @@ void test_ansi_color(void)
 {
   // int ansi_color_parse(const char *str, struct AnsiColor *ansi, struct AttrColorList *acl, bool dry_run);
 
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   curses_colors_init();
   COLOR_PAIRS = 256;
diff --git a/test/color/attr.c b/test/color/attr.c
index 619fb85c..6bba8d2f 100644
--- a/test/color/attr.c
+++ b/test/color/attr.c
@@ -58,7 +58,7 @@ void test_attr_colors(void)
 {
   COLOR_PAIRS = 32;
   curses_colors_init();
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   {
     attr_color_free(NULL);
diff --git a/test/color/color_dump.c b/test/color/color_dump.c
index 3a194977..7293e5ea 100644
--- a/test/color/color_dump.c
+++ b/test/color/color_dump.c
@@ -51,7 +51,7 @@ void test_color_dump(void)
   regex_colors_init();
   simple_colors_init();
 
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   struct AttrColor ac = { 0 };
 
diff --git a/test/color/simple.c b/test/color/simple.c
index 6b2044a6..ee7dc35d 100644
--- a/test/color/simple.c
+++ b/test/color/simple.c
@@ -43,7 +43,7 @@ void test_simple_colors(void)
 {
   MuttLogger = log_disp_null;
 
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   simple_colors_init();
 
diff --git a/test/common.c b/test/common.c
index 900ca727..7e8520d6 100644
--- a/test/common.c
+++ b/test/common.c
@@ -105,7 +105,7 @@ bool test_neomutt_create(void)
   NeoMutt = neomutt_new(cs);
   TEST_CHECK(NeoMutt != NULL);
 
-  TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(cs, Vars));
 
   init_tmp_dir(NeoMutt);
 
diff --git a/test/config/account.c b/test/config/account.c
index f25911f9..1ca86585 100644
--- a/test/config/account.c
+++ b/test/config/account.c
@@ -48,7 +48,7 @@ void test_config_account(void)
   int rc = 0;
   struct ConfigSet *cs = NeoMutt->sub->cs;
 
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
 
   notify_observer_add(NeoMutt->notify, NT_CONFIG, log_observer, 0);
diff --git a/test/config/bool.c b/test/config/bool.c
index 2951cf05..2cc2c998 100644
--- a/test/config/bool.c
+++ b/test/config/bool.c
@@ -820,7 +820,7 @@ void test_config_bool(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/dump.c b/test/config/dump.c
index 43581298..ddfedb33 100644
--- a/test/config/dump.c
+++ b/test/config/dump.c
@@ -210,7 +210,7 @@ struct ConfigSet *create_sample_data(void)
   cs_register_type(cs, &CstSort);
   cs_register_type(cs, &CstString);
 
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return NULL;
 
   return cs;
diff --git a/test/config/enum.c b/test/config/enum.c
index 441edf84..ed581615 100644
--- a/test/config/enum.c
+++ b/test/config/enum.c
@@ -699,7 +699,7 @@ void test_config_enum(void)
   struct ConfigSet *cs = sub->cs;
 
   StartupComplete = false;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   StartupComplete = true;
 
diff --git a/test/config/helpers.c b/test/config/helpers.c
index c23844a8..415ed199 100644
--- a/test/config/helpers.c
+++ b/test/config/helpers.c
@@ -89,7 +89,7 @@ static struct ConfigDef Vars[] = {
 
 void test_config_helpers(void)
 {
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   struct ConfigSubset *sub = NeoMutt->sub;
 
diff --git a/test/config/initial.c b/test/config/initial.c
index d551a50f..960437b9 100644
--- a/test/config/initial.c
+++ b/test/config/initial.c
@@ -96,7 +96,7 @@ void test_config_initial(void)
   struct ConfigSubset *sub = NeoMutt->sub;
   struct ConfigSet *cs = sub->cs;
 
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
 
   notify_observer_add(NeoMutt->notify, NT_CONFIG, log_observer, 0);
diff --git a/test/config/long.c b/test/config/long.c
index c161d05f..5c236f39 100644
--- a/test/config/long.c
+++ b/test/config/long.c
@@ -868,7 +868,7 @@ void test_config_long(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/mbtable.c b/test/config/mbtable.c
index 59797c74..18503288 100644
--- a/test/config/mbtable.c
+++ b/test/config/mbtable.c
@@ -709,7 +709,7 @@ void test_config_mbtable(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/myvar.c b/test/config/myvar.c
index 66b59f56..b5ab6ced 100644
--- a/test/config/myvar.c
+++ b/test/config/myvar.c
@@ -601,7 +601,7 @@ void test_config_myvar(void)
   struct ConfigSet *cs = sub->cs;
 
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
 
diff --git a/test/config/number.c b/test/config/number.c
index 723b7249..9964488e 100644
--- a/test/config/number.c
+++ b/test/config/number.c
@@ -953,7 +953,7 @@ void test_config_number(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/path.c b/test/config/path.c
index 18595c15..f550075c 100644
--- a/test/config/path.c
+++ b/test/config/path.c
@@ -677,7 +677,7 @@ void test_config_path(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/quad.c b/test/config/quad.c
index 4e0f1ba6..80e1402d 100644
--- a/test/config/quad.c
+++ b/test/config/quad.c
@@ -742,7 +742,7 @@ void test_config_quad(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/regex.c b/test/config/regex.c
index 5632d3ac..55d62c5f 100644
--- a/test/config/regex.c
+++ b/test/config/regex.c
@@ -725,7 +725,7 @@ void test_config_regex(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/set.c b/test/config/set.c
index 55b028bb..9613d328 100644
--- a/test/config/set.c
+++ b/test/config/set.c
@@ -102,9 +102,9 @@ bool degenerate_tests(struct ConfigSet *cs)
     return false;
   if (!TEST_CHECK(cs_register_type(cs, NULL) == false))
     return false;
-  if (!TEST_CHECK(cs_register_variables(cs, NULL, DT_NO_FLAGS) == false))
+  if (!TEST_CHECK(cs_register_variables(cs, NULL) == false))
     return false;
-  if (!TEST_CHECK(cs_register_variables(NULL, Vars, DT_NO_FLAGS) == false))
+  if (!TEST_CHECK(cs_register_variables(NULL, Vars) == false))
     return false;
 
   if (!TEST_CHECK(cs_str_native_get(NULL, "apple", NULL) == INT_MIN))
@@ -391,7 +391,7 @@ void test_config_set(void)
   cs_register_type(cs, &CstBool);
   cs_register_type(cs, &CstBool); /* second one should fail */
 
-  if (TEST_CHECK(!cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (TEST_CHECK(!cs_register_variables(cs, Vars)))
   {
     TEST_MSG("Expected error");
   }
diff --git a/test/config/slist.c b/test/config/slist.c
index 9b92865b..cfb82206 100644
--- a/test/config/slist.c
+++ b/test/config/slist.c
@@ -1126,7 +1126,7 @@ bool slist_test_separator(struct ConfigDef vars[], struct Buffer *err)
 
   StartupComplete = false;
   cs_register_type(cs, &CstSlist);
-  if (!TEST_CHECK(cs_register_variables(cs, vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, vars)))
     return false;
   StartupComplete = true;
 
@@ -1173,7 +1173,7 @@ void test_config_slist(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, VarsOther, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, VarsOther)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/sort.c b/test/config/sort.c
index 36ad857a..cfe6ed0c 100644
--- a/test/config/sort.c
+++ b/test/config/sort.c
@@ -787,7 +787,7 @@ void test_config_sort(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
@@ -797,7 +797,7 @@ void test_config_sort(void)
   set_list(cs);
 
   /* Register a broken variable separately */
-  if (!TEST_CHECK(cs_register_variables(cs, Vars2, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars2)))
     return;
 
   struct Buffer *err = buf_pool_get();
diff --git a/test/config/string.c b/test/config/string.c
index 68d4ceb6..0b3d5973 100644
--- a/test/config/string.c
+++ b/test/config/string.c
@@ -795,7 +795,7 @@ void test_config_string(void)
 
   StartupComplete = false;
   dont_fail = true;
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
   dont_fail = false;
   StartupComplete = true;
diff --git a/test/config/subset.c b/test/config/subset.c
index 23bd8fd8..db61f0be 100644
--- a/test/config/subset.c
+++ b/test/config/subset.c
@@ -51,7 +51,7 @@ void test_config_subset(void)
 
   struct ConfigSet *cs = cs_new(30);
   cs_register_type(cs, &CstNumber);
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
 
   struct NeoMutt *n = neomutt_new(cs);
diff --git a/test/config/synonym.c b/test/config/synonym.c
index b572f2b8..878f7120 100644
--- a/test/config/synonym.c
+++ b/test/config/synonym.c
@@ -191,10 +191,10 @@ void test_config_synonym(void)
   struct ConfigSubset *sub = NeoMutt->sub;
   struct ConfigSet *cs = sub->cs;
 
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
 
-  if (cs_register_variables(cs, Vars2, DT_NO_FLAGS))
+  if (cs_register_variables(cs, Vars2))
   {
     TEST_MSG("Test should have failed");
     return;
diff --git a/test/config/variable.c b/test/config/variable.c
index a5e038f0..640cd794 100644
--- a/test/config/variable.c
+++ b/test/config/variable.c
@@ -46,7 +46,7 @@ void test_config_variable(void)
   struct ConfigSubset *sub = NeoMutt->sub;
   struct ConfigSet *cs = sub->cs;
 
-  if (!TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(cs, Vars)))
     return;
 
   struct Buffer *err = buf_pool_get();
diff --git a/test/convert/mutt_get_content_info.c b/test/convert/mutt_get_content_info.c
index ea91b3c9..481a7411 100644
--- a/test/convert/mutt_get_content_info.c
+++ b/test/convert/mutt_get_content_info.c
@@ -64,7 +64,7 @@ void test_mutt_get_content_info(void)
 
   struct ConfigSubset *sub = NeoMutt->sub;
   struct ConfigSet *cs = sub->cs;
-  TEST_CHECK(cs_register_variables(cs, CharsetVars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(cs, CharsetVars));
 
   struct Body *body = mutt_body_new();
   struct Content *content = mutt_get_content_info(buf_string(fname), body, sub);
diff --git a/test/idna/mutt_idna_intl_to_local.c b/test/idna/mutt_idna_intl_to_local.c
index 471587cc..b4f5c02a 100644
--- a/test/idna/mutt_idna_intl_to_local.c
+++ b/test/idna/mutt_idna_intl_to_local.c
@@ -45,7 +45,7 @@ void test_mutt_idna_intl_to_local(void)
   // char *mutt_idna_intl_to_local(const char *user, const char *domain, uint8_t flags);
 
 #ifdef HAVE_LIBIDN
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   {
     const char *addr = mutt_idna_intl_to_local(NULL, "banana", MI_NO_FLAGS);
diff --git a/test/idna/mutt_idna_local_to_intl.c b/test/idna/mutt_idna_local_to_intl.c
index f4c30420..76b08d4d 100644
--- a/test/idna/mutt_idna_local_to_intl.c
+++ b/test/idna/mutt_idna_local_to_intl.c
@@ -45,7 +45,7 @@ void test_mutt_idna_local_to_intl(void)
   // char * mutt_idna_local_to_intl(const char *user, const char *domain);
 
 #ifdef HAVE_LIBIDN
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   {
     const char *addr = mutt_idna_local_to_intl(NULL, "banana");
diff --git a/test/neo/neomutt_new.c b/test/neo/neomutt_new.c
index 421a5102..a0a162a5 100644
--- a/test/neo/neomutt_new.c
+++ b/test/neo/neomutt_new.c
@@ -47,7 +47,7 @@ void test_neomutt_new(void)
   {
     struct ConfigSet *cs = cs_new(30);
     cs_register_type(cs, &CstNumber);
-    TEST_CHECK(cs_register_variables(cs, Vars, DT_NO_FLAGS));
+    TEST_CHECK(cs_register_variables(cs, Vars));
 
     struct NeoMutt *n = neomutt_new(cs);
     TEST_CHECK(n != NULL);
diff --git a/test/parse/parse_rc.c b/test/parse/parse_rc.c
index 0ca955a1..52cfe6c0 100644
--- a/test/parse/parse_rc.c
+++ b/test/parse/parse_rc.c
@@ -131,7 +131,7 @@ void test_parse_rc(void)
   rc = parse_rc_buffer(NULL, NULL, NULL);
   TEST_CHECK(rc == MUTT_CMD_SUCCESS);
 
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
   cs_str_initial_set(NeoMutt->sub->cs, "from", "rich at flatcap.org", NULL);
   cs_str_reset(NeoMutt->sub->cs, "from", NULL);
   test_parse_set();
diff --git a/test/parse/parse_rc_line.c b/test/parse/parse_rc_line.c
index 5c75c83c..8a68f830 100644
--- a/test/parse/parse_rc_line.c
+++ b/test/parse/parse_rc_line.c
@@ -1007,7 +1007,7 @@ static bool test_path_expanding(struct Buffer *err)
 
 void test_command_set(void)
 {
-  if (!TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, ConfigVars, DT_NO_FLAGS)))
+  if (!TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, ConfigVars)))
   {
     TEST_MSG("Failed to register config variables");
     return;
diff --git a/test/pattern/leak.c b/test/pattern/leak.c
index 4aaa9bc6..3795a73e 100644
--- a/test/pattern/leak.c
+++ b/test/pattern/leak.c
@@ -48,7 +48,7 @@ static void test_one_leak(const char *pattern)
 void test_mutt_pattern_leak(void)
 {
   MuttLogger = log_disp_null;
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   test_one_leak("~E ~F | ~D");
   test_one_leak("~D | ~E ~F");
diff --git a/test/rfc2047/rfc2047_encode_addrlist.c b/test/rfc2047/rfc2047_encode_addrlist.c
index f9da4f47..23235b62 100644
--- a/test/rfc2047/rfc2047_encode_addrlist.c
+++ b/test/rfc2047/rfc2047_encode_addrlist.c
@@ -43,7 +43,7 @@ void test_rfc2047_encode_addrlist(void)
 {
   // void rfc2047_encode_addrlist(struct Address *addr, const char *tag);
 
-  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars, DT_NO_FLAGS));
+  TEST_CHECK(cs_register_variables(NeoMutt->sub->cs, Vars));
 
   {
     rfc2047_encode_addrlist(NULL, "apple");
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://mailman.neomutt.org/pipermail/neomutt-devel-neomutt.org/attachments/20231223/1a6ca450/attachment.sig>


More information about the neomutt-devel mailing list