Dear all, I’ve recently been re-implementing some of my projects in L3, and finding myself having to jump through some hoops to get things I had working smoothly in pgfkeys work equivalently well with l3keys. In particular, filtering and redirecting keys has been a bit of a chore. In light of this, I have a couple of suggestions for features that could be added to the module in due course (to better illustrate what I have in mind, I’ve written a quick-and-dirty implementation - appended at the bottom of this email; the code seems to work, but I fully expect more experienced people could greatly improve it). 1) It would be good to add a .meta:nn property that takes a path as its first argument, so that we could do things like \keys_define:nn { module / subgroup-i } { key-i .code:n = { < code > } } \keys_define:nn { module / subgroup-ii } { key-ii .meta:nn = { module / subgroup-i } { key-i = #1 } } instead of having to write \keys_define:nn { module / subgroup-ii } { key-i .code:n = { \keys_set:nn { module / subgroup-i } { key-i = #1 } } } as is the case right now. 2) It would also be useful to provide a \keys_set_in_subgroups:nnn command which would take a list of subgroups in the second argument-place, and would cycle through all the subgroups looking for keys given in the third argument-place. Then we could write things like \keys_set_in_subgroups:nnn { module } { subgroup-i , subgroup-ii } { key-i = foo , key-ii = bar } instead of \keys_set:nn { module / subgroup-i } { key-i = foo } \keys_set:nn { module / subgroup-ii } { key-ii = bar } More importantly, we could then easily define user commands that set different subsets of keys. A further command \keys_set_known_in_subgroups:nnnN could then be used to catch keys that don’t exist in any of the specified subgroups. If this suggestion is accepted, it would also be useful to then extend l3keys2e with something like \ProcessKeysOptionsInSoubgroups { < module > } { < subgroup list > } so we can use filtering in this context as well. Anyhow, below is some code that does these things, but does need some improvement. Please let me know what you think. Best regards, Jura Pintar \cs_new_protected:Npn \__keys_meta_make:nn #1#2 { \__keys_cmd_set:Vo \l_keys_path_tl { \exp_after:wN \keys_set:nn {#1} {#2} } } \cs_new_protected:Npn \__keys_meta_make:nx #1#2 { \__keys_cmd_set:nx { \l_keys_path_tl } { \exp_not:N \keys_set:nn \exp_not:n { {#1} } {#2} } } \cs_new_protected:Npn \__keys_meta_make:xx #1#2 { \__keys_cmd_set:nx { \l_keys_path_tl } { \exp_not:N \keys_set:nn {#1} {#2} } } \cs_new_protected:cpn { \c__keys_props_root_tl .meta:nn } #1 { \__keys_meta_make:nn #1 } \cs_new_protected:cpn { \c__keys_props_root_tl .meta:nx } #1 { \__keys_meta_make:nx #1 } \cs_new_protected:cpn { \c__keys_props_root_tl .meta:xx } #1 { \__keys_meta_make:xx #1 } \clist_new:N \l__keys_leftover_clist \prop_new:N \l__keys_leftover_prop \cs_generate_variant:Nn \keyval_parse:NNn { NNo } \__msg_kernel_new:nnnn { kernel } { key-unknown-in-subgroups } { The~key~’#1’~is~unknown~and~is~being~ignored. } { A~key~called~’#1’~does~not~exist~in~any~specified~subgroup~of~ the~module~’#2’.\\ Check~that~you~have~spelled~the~key~name~correctly. } \cs_new_protected:Npn \keys_set_in_subgroups:nnn #1#2#3 { \__keys_set_in_subgroups:onnn { \l__keys_module_tl } {#1} {#2} {#3} \clist_map_inline:Nn \l__keys_unknown_clist { \__msg_kernel_error:nnnn { kernel } { key-unknown-in-subgroups } {##1} {#1} } } \cs_new_protected:Npn \__keys_set_in_subgroups:nnnn #1#2#3#4 { \clist_set:Nn \l__keys_unknown_clist {#4} \cs_set_eq:NN \__keys_execute_unknown: \__keys_execute_unknown_alt: \clist_map_inline:nn {#3} { \tl_set:Nx \l__keys_module_tl { \tl_to_str:n { #2 / ##1 } } \clist_set_eq:NN \l__keys_leftover_clist \l__keys_unknown_clist \clist_clear:N \l__keys_unknown_clist \keyval_parse:NNo \__keys_set_elt:n \__keys_set_elt:nn { \l__keys_leftover_clist } } \cs_set_eq:NN \__keys_execute_unknown: \__keys_execute_unknown_std: \tl_set:Nn \l__keys_module_tl {#1} } \cs_generate_variant:Nn \__keys_set_in_subgroups:nnnn { o } \cs_generate_variant:Nn \keys_set_in_subgroups:nnn { nVn , nVV , nVv , nVo , nvn , nvV , nvv , nVo , nno } \cs_new_protected:Npn \keys_set_known_in_subgroups:nnnN #1#2#3#4 { \__keys_set_in_subgroups:onnn { \l__keys_module_tl } {#1} {#2} {#3} \clist_set_eq:NN #4 \l__keys_unknown_clist } \cs_generate_variant:Nn \keys_set_known_in_subgroups:nnnN { nVn , nVV , nVv , nVo , nvn , nvV , nvv , nVo , nno }