123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130openCoretypenargs=[`Exactlyofint|`List|`At_most_one|`At_least_one]letnargs_of_msgpack=function|Msgpack.Nil->Ok(`Exactly0)|Integeri->Ok(`Exactlyi)|String"*"->Ok`List|String"?"->Ok`At_most_one|String"+"->Ok`At_least_one|_->Or_error.error_string"malformed nargs";;typeaddr_type=[`Lines|`Args|`Buffers|`Loaded_bufs|`Windows|`Tabs]letaddr_of_msgpack=function|Msgpack.Nil|String"lines"->Ok`Lines|String"arguments"->Ok`Args|String"buffers"->Ok`Buffers|String"loaded_buffers"->Ok`Loaded_bufs|String"windows"->Ok`Windows|String"tabs"->Ok`Tabs|_->Or_error.error_string"malformed addr";;typerange_type=|Rangeof[`Defaults_to_current_line|`Defaults_to_whole_file|`Defaults_to_line_nrofint]|Countofintletconvert_rangerangecount=letopenOr_error.Let_syntaxin(* This way, we can handle [range] and [combine] with one joined error. *)let%bindboth=Or_error.combine_errors[range;count]inletrange,count=matchbothwith|[range;count]->range,count|_->assertfalsein(* These combinations were determined experimentally and may be subject to change with
future versions of neovim.
Observed combinations:
-range gives range = "." and count = Nil
-range=% gives range = "%" and count = Nil
-range=N gives range = "N" and count = Nil
-count=N gives range = "N" and count = "N" *)matchrange,countwith|Msgpack.Nil,Msgpack.Nil->returnNone|String".",Nil->return(Some(Range`Defaults_to_current_line))|String"%",Nil->return(Some(Range`Defaults_to_whole_file))|Strings,Nil->let%mapn=Or_error.try_with(fun()->Int.of_strings)inSome(Range(`Defaults_to_line_nrn))|String_,Strings->let%mapn=Or_error.try_with(fun()->Int.of_strings)inSome(Countn)|_,_->Or_error.error_string"invalid or unknown [range]/[count] combination.";;letstring_or_nil=function|Msgpack.Nil->OkNone|Msgpack.Strings->Ok(Somes)|_->Or_error.error_string"called [string_or_nil] on wrong type";;typet={name:string;definition:string;script_id:int;bang:bool;bar:bool;register:bool;nargs:nargs;complete:stringoption;complete_arg:stringoption;range:range_typeoption;addr:addr_type}letof_msgpackmsg=letresult=letopenOr_error.Let_syntaxinletfind_keymsextract=Map.find_or_errorms>>=extractinlet%bindmap=Extract.map_of_msgpack_mapmsginlet%bindname=find_keymap"name"Extract.stringinlet%binddefinition=find_keymap"definition"Extract.stringinlet%bindscript_id=find_keymap"script_id"Extract.intinlet%bindbang=find_keymap"bang"Extract.boolinlet%bindbar=find_keymap"bar"Extract.boolinlet%bindregister=find_keymap"register"Extract.boolinlet%bindnargs=find_keymap"nargs"nargs_of_msgpackinlet%bindcomplete=find_keymap"complete"string_or_nilinlet%bindcomplete_arg=find_keymap"complete"string_or_nilinletrange_input=Map.find_or_errormap"range"inletcount_input=Map.find_or_errormap"count"inlet%bindrange=convert_rangerange_inputcount_inputinlet%bindaddr=find_keymap"addr"addr_of_msgpackinreturn{name;definition;script_id;bang;bar;register;nargs;complete;complete_arg;range;addr}inOr_error.tag~tag:"malformed command map"result;;