Support user-defined verbs
miller verbs are great. Easy to use, saves key strokes and easy to understand. It would be nice to extend those benefits to user-defined verbs.
Proposal
Users can create new verbs by registering them using below function. This function will be called in a miller file loaded using --[m]load.
register_verb(func, name, description, flags)
nameis stringdescriptionis string for use inmlr helpflagsis an array offlagwhich is a map with keysshort,long,description,type,default. At least one ofshortorlongis required. Rest are of them are optional.typecan be"bool","single", or"multi". default is"single"."multi"means it can occur multiple times. e.g.verb -f arg1-f arg2 -f arg3. Accessed in the function as a listarg["f"]will be["arg1", "arg2", "arg3"].- when
typeisbool, it can be turned off with--no-prefix. i.e.--no-longname. boolflags can be coalesced. i.e.-xyz foois same as-x -y -z foo.- one of the flag can have
longset to[POS]which refers to positional argument.typeis alwayssingle funcis a miller function that will be called with one argumentargs. It is a map with passed flags.
Example
register_verb(bconv, "bconv", "Convert bytes to KB, MB, GB or TB", [
{
"short": "s",
"long":"source",
"type":"single",
"default":"B",
"description":"Source unit. One of B, KB, MB, GB"
},
{
"short": "t",
"long":"target",
"type":"single",
"default": "auto",
"description":"Target unit. One of B, KB, MB, GB, auto. If auto, appropriate unit is chosen"
},
{
"short": "x",
"long":"suffix",
"type":"bool",
"default":true,
"description":"Add suffix after conversion. E.g. 2.4 MB"
},
{
"long":"[POS]",
"description":"comma separated list of fields to convert"
}
]
)
func bconf(args) {
if (args["suffix"]) { ... }
}
Namespace
- Keep user defined verbs same namespace as standard ones. (similar to user defined functions).
- Have user-defined verbs start with capital letter. Similar to
gofunctions. - [my choice] Prefix user-defined verbs with
u:or a different prefix. E.g.mlr --l2p u:bconv Memory,Swap then head.
@balki so the verb-implementation language would be the Miller DSL?
It seems to me a great idea
Scusami per la brevità, ti sto scrivendo dal cellulare.
website: https://medium.com/tantotanto 38° 7' 48" N, 13° 21' 9" E EPSG:4326
Il gio 17 lug 2025, 17:24 Balki @.***> ha scritto:
balki created an issue (johnkerl/miller#1836) https://github.com/johnkerl/miller/issues/1836
miller verbs are great. Easy to use, saves key strokes and easy to understand. It would be nice to extend those benefits to user-defined verbs. Proposal
Users can create new verbs by registering them using below function. This function will be called in a miller file loaded using --[m]load.
register_verb(func, name, description, flags)
- name is string
- description is string for use in mlr help
- flags is an array of flag which is a map with keys short, long, description, type, default. Atleast one of short or long is required. Rest are of them are optional.
- type can be "bool", "single", or "multi". default is "single". "multi" means it can occur multiple times. e.g. verb -f arg1-f arg2 -f arg3. Accessed in the function as a list arg["f"] will be ["arg1", "arg2", "arg3"].
- when type is bool, it can be turned off with --no- prefix. i.e. --no-longname.
- bool flags can be coalesced. i.e. -xyz foo is same as -x -y -z foo.
- one of the flag can have long set to [POS] which refers to positional argument. type is always single
- func is a miller function that will be called with one argument args. It is a map with passed flags.
Example
register_verb(bconv, "bconv", "Convert bytes to KB, MB, GB or TB", [ { "short": "s", "long":"source", "type":"single", "default":"B", "description":"Source unit. One of B, KB, MB, GB" }, { "short": "t", "long":"target", "type":"single", "default": "auto", "description":"Target unit. One of B, KB, MB, GB, auto. If auto, appropriate unit is chosen" }, { "short": "x", "long":"suffix", "type":"flag", "default":true, "description":"Add suffix after conversion. E.g. 2.4 MB" }, { "long":"[POS]", "description":"comma seperated list of fields to convert" } ] )
func bconf(args) { if (args["suffix"]) { ... } }
Namespace
- Keep user defined verbs same namespace as standard ones. (similar to user defined functions).
- Have user-defined verbs start with capiltal letter. Similar to go functions.
- [my choice] Prefix user-defined verbs with u: or a different prefix. E.g. mlr --l2p u:bconv Memory,Swap then head.
— Reply to this email directly, view it on GitHub https://github.com/johnkerl/miller/issues/1836, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAHPD6QAVWB2EPGEQ5LR533I65ZTAVCNFSM6AAAAACBYFN5K6VHI2DSMVQWIX3LMV43ASLTON2WKOZTGIZTSOJZGE4TQMI . You are receiving this because you are subscribed to this thread.Message ID: @.***>
@balki so the verb-implementation language would be the Miller DSL?
Yes. I think miller DSL can handle most use-cases and would be fast enough. Using golang plugin system will require to recompile and not easy for many users.
This proposal does not cover verbs that need to look across multiple records. May be we can have another register function like
register_verb3(func_begin, func_process, func_end, name, desc, flags). func_end, can emit all records after aggregating.
Using golang plugin system will require to recompile and not easy for many users.
100% agree 😎