chk.txt  Utility used to check arguments of commands and functions


CONTENTS                                                      chk-contents

    1. Intro                                      chk-intro

    2. Functionality provided                     chk-functionality

        2.1. Functions                            chk-functions

        2.2. Checks                               chk-checks

        2.3. Models                               chk-model

        2.4. Transformations                      chk-trans

    3. Example usage                              chk-usage


1. Intro                                                         chk-intro

This plugin provides the ability to check whether function or command 

arguments match specific model or whether some value matches specific model.


    ∙ Checks a list of arguments against specified model

    ∙ Checks a single value against specified model

    ∙ Provides a way to specify default values for optional arguments

    ∙ Provides a way to check a single value, convert it, and check again

Plugin requires load plugin to work.


2. Functionality provided                                chk-functionality

This plugin provides two functions. Functions are accessed via dictionary 

returned by load-func-getfunctions function.


2.1. Functions                                               chk-functions


checkargument({check}{argument}) :: Check -> a -> Bool

        Checks data {argument} using check {check}. For possible {check} 

        arguments see chk-checks


checkarguments({model}{arguments}) :: Model -> [a] -> Bool

        Checks argument list {arguments} (it must be a single list!) using 

        model {model}. For possible {model} arguments see chk-model.


2.2. Checks                                                     chk-checks

All checks are lists of three or two elements. First element is the name of 

a check. Second is an argument of the check. Third is optional and it contains 

the error message displayed when the check fails.

Check name  Check argument and description


in          [a] (any list)

            Checks whether {argument} is in list {checkargument}.


regex       Regex (correct regular expression)

            Checks whether {argument} is a string and matches regular 

            expression {checkargument}.


func        (a -> Bool) (any function that takes {argument} and

                         returns 1 or 0)

            Checks, whether function being supplied by {argument} as an 

            {argument} returns true. Note that this function must not echo any 

            warnings using :echoerr: they will be captured by :try and 

            check will fail.


type        Int (any integer from 0 to 5)

            Checks, whether type of {argument} is {checkargument}.


isfunc      Bool (0 or 1)

            Checks, whether {argument} is function reference and it is 

            callable. It is similar to chk-check-type when {checkargument} 

            is 2, but prevents from supplying function references that are not 

            callable (for example, if this reference points to script-local 

            function). If {checkargument} is 1, then check also accepts 

            strings with function names.


bool        _ (argument is ignored)

            Checks, whether {argument} is either 0 or 1.


eval        String (any correct expression)

            Checks, whether eval({checkargument}) is true. Inside this check 

            a:Arg is set to {argument}Note that evaluated expression must 

            not echo any warnings using :echoerr: they will be captured by 

            :try and check will fail.


keyof       Dictionary

            Checks, whether {argument} is a key of {checkargument}{argument} 

            must be of a type String.


hkey        String

            Checks, whether {argument} is a Dictionary and has key 



equal       a (everything)

            Checks, whether {argument} is identical to {checkargument}.


var         String (either empty or contains comma-delimited variable type

                    names: buffer, window, tabpage, global, vim, option, any)

            Checks, whether {argument} is a variable name, this 

            variable exists and has specified type. (`option' variable names 

            must start with `&', others with `b:', `w:', `t:', `g:' or `v:' 

            for buffer, window, tabpage, global or vim responsively. See 

            internal-variables for details.)


any         _ (argument is ignored)

            Always true.


num         (Fractional a) => Either (Either a String, a) (a)

                              (list with one or two elements)

            Checks whether {argument} is a number (depending on a type of 

            first number in {checkargument} it must have a type either Integer 

            or any of Integer and Fload) from first element of {checkargument} 

            (if it is not equal to empty string) to the second element of 

            {checkargument} (if it exists).

            Examples: >

                Check               Argument   Result

                ["num", [0]]        1          True

                ["num", [0]]        -1         False

                ["num", [0]]        1.0        False

                ["num", [0.0]]      1.0        True

                ["num", [0.0]]      1          True

                ["num", ["", 0]]    1          False

                ["num", ["", 0]]    -1         True

                ["num", ["", 0]]    -1.0       False

                ["num", [0, 2]]     0          True

                ["num", [0, 2]]     3          False

                ["num", [0, 2]]     -1         False

                ["num", [0, 2.0]]   1.0        False

                ["num", [0.0, 2.0]] 1.0        True

                ["num", [0.0, 2]]   1.0        True

nums         (see above)                                    chk-check-nums

            Just like chk-check-num, but before doing a check it runs 



isreg       _ (argument is ignored)

            Check whether {argument} is a correct regular expression.


hlgroup     _ (argument is ignored)

            Check whether {argument} is a name of existing highlight group.


file        String

            Test, whether {argument} is a filename, which

            {checkargument}  Meaning

                   r         exists and is readable;

                   rw        exists and is writeable;

                   d         exists and is a directory;

                   x         exists and is executable;

                   dw        exists, is a directory and is writeable;

                   w         either exists and is writeable or does not

                             exist, but is in directory where we could 



len         Either (Integer, Integer) (Integer) (list with one or two


            Checks whether {argument} is a list with length from 

            {checkargument}[0] to {checkargument}[1] (or infinity if it is not 

            present). Use regular expressions to test for string length.


chklst      [ Check ] (list of checks)

            Checks whether {argument} is a list with length equal to length of 

            {checkargument} and every element in {argument} matches Check in 

            the identical position.


optlst      ([ Check ], [ Check ]) (two lists of checks)

            Checks whether {argument} is a list with length not less then 

            length of {checkargument}[0] and not greater then sum of 

            lengths of {checkargument}[0] and {checkargument}[1], first 

            len({checkargument}[0]) elements of {argument} match checks in 

            {checkargument}[0] and other elements of {argument} match checks 

            in {checkargument}[1].


alllst      Check

            Checks whether {argument} is a list and every element in 

            {argument} matches {checkargument}.


dict        [(Check, Check)] (list of lists of two checks)

            If {argument} is a dictionary then for every key of {argument} if 

            it matches left Check and value does not match right check return 

            False. Also return False if some key matches none of right checks.


map         ({CheckName}, [ {CheckArgument} ])

            For every {CheckArgument} in list {checkargument}[1] check whether 

            {argument} matches check [{CheckName}{CheckArgument}].


allorno     [ Check ] (list of checks)

            Check succeeds either if {argument} matches all Checks in 

            {checkargument} or none of Checks in {checkargument}.


not         Check

            Check, whether {argument} does not match {checkargument}.


or          [ Check ] (list of checks)

            Check, whether {argument} matches any of checks in 



and         [ Check ] (list of checks)

            Checks, whether {argument} matches all of checks in 



2.3. Models                                                      chk-model

{model} is a dictionary with required key "model" and some other keys, which 

depend on "model".

Model     Description


simple    Required keys: "required" :: [ ArgTrans ] (list of transformations)

          Meaning: there must be exactly len("required") arguments

                   in {arguments}, all must be successfully 

                   transformed by appropriate ArgTrans.


              If we need to check arguments to the pow() function: >

              pow(Float, Float) -> Float

                  {    "model": "simple",

                    "required": [["or", ["type", type(0.0)],

                                        ["type", type(0)]],

                                 ["or", ["type", type(0.0)],

                                        ["type", type(0)]]] }



optional  Required keys: no

          Optional keys: "required" :: [ ArgTrans ]

                         "optional" :: [(ArgTrans, ArgTrans, a)]

                              (list of lists of three elements: transformation 

                              for present argument, transformation for default 

                              value and default value)

                         "next" :: ArgTrans

          Meaning: there must be at least len("required") arguments (or 0 if

                   it is not present) and at most len("optional") optional 

                   arguments (unless "next" key is present). If some optional 

                   argument is present it is transformed by first ArgTrans. If 

                   it is not present, then third value in list is transformed 

                   using the second ArgTrans. After all optional arguments 

                   were processed, all other arguments are transformed using 

                   ArgTrans from "next" key. If there is no "next" key and 

                   number of arguments is greater then number of required plus 

                   number of optional arguments, then 0 is returned, 

                   indicating that an error occured.


              If we need to check arguments to the matchstr() function: >

              matchstr(String, Regex[, UInteger[, UInteger]])

                  {   "model": "optional",

                   "required": [["type", type("")],

                                ["isreg", ""]],

                   "optional": [[["num", [0]], {}, 0],

                                [["num", [0]], {}, 0]] }



prefixed  Required keys: no

          Optional keys: "required" :: [ ArgTrans ]

                         "optional" :: [(ArgTrans, ArgTrans, a)]

                         "prefrequired" :: {prefix: ArgTrans}

                              (dictionary with values identical to 

                              "required" values)

                         "prefoptional" :: {prefix: (ArgTrans,

                                                     ArgTrans, a)}

                              (dictionary with values identical to 

                              "optional" values)

                         "preflist" :: [ String ] (list of


                         "allowtrun" :: Bool

                         "altpref" :: [ prefix ] (list of strings)


              Command must look like that: >

                   Command [required_arguments]

                         \ [optional_arguments]

                         \ [{prefix} {argument}]

                         \ [{prefixFromPreflist} [arguments]]


              Here [required_arguments] are described in "required" key and 

              are handled just like in chk-model-simple

              [optional_arguments] are described in "optional" key and are 

              handled just like in chk-model-optional, but with one 

              difference: [optional_arguments] must contain none of the keys 

              of "prefrequired" and "prefoptional" dictionaries. Then for all 

              keys from "prefrequired" and "prefoptional" not listed in 

              "preflist" if in the arguments list there is a sequence [{key}

              {value}], then extend the last entry in arguments list (it will 

              always be a dictionary) with { {key}{value} } pair. Prefixes 

              listed in "altpref" does not require any values, though they 

              make take one if they are present in "prefrequired" or 

              "prefoptional" as well, so if `prefix' is in "altpref" and in 

              "prefrequired", then either of `prefix' (=`prefix 1'), 

              `noprefix' (=`prefix 0', default) and `prefix {value}' are 

              possible. If some key from "prefrequired" or "prefoptional" is 

              listed in "preflist" then all arguments starting with one equal 

              to this key and ending with one of the keys from "prefrequired" 

              or "prefoptional" are added to the list. Last entry in arguments 

              list will be extended with { {key}{list} } pair then. Key 

              "allowtrun" denies or allows (default: allow) reducing prefixes. 

              For example, if there are prefixes “columns”, “count” and 

              “print” then if reducing is allowed “columns” may be reduced to 

              “col”, “count” to “cou” and “print” to “p”. Presence of either 

              "optional" or "preflist" keys denies reducing.

              Examples: >

                  {"model": "prefixed",

                   "required": [{}],

                   "optional": [[{}, {}, "def"]],

                   "prefrequired": {"for": {}, "in": {}},

                   "prefoptional": {"using": [{}, {}, "defU",

                                    "list": [{}, {}, ["defL"]]},

                   "preflist": ["in", "list"]}

                  Cmdline => Result:

                  required optional for F in I using U list L =>

                            ["required", "optional", {"for": "F",

                                                      "in": ["I"],

                                                      "using": "U",

                                                      "list": ["L"]}]

                  required for F in I using U list L =>

                            ["required", "def", {"for": "F",

                                                 "in": ["I"],

                                                 "using": "U",

                                                 "list": ["L"]}]

                  required four for F in I using U list L =>

                            ["required", "four", {"for": "F",

                                                  "in": ["I"],

                                                  "using": "U",

                                                  "list": ["L"]}]

                  required for F in I1 I2  =>

                            ["required", "def", {"for": "F",

                                                 "in": ["I1", "I2"],

                                                 "using": "defU",

                                                 "list": ["defL"]}]

                  required for F in I1 I2 list L1 L2 =>

                            ["required", "def", {"for": "F",

                                                 "in": ["I1", "I2"],

                                                 "using": "U",

                                                 "list": ["L1", "L2"]}]



actions   Required keys: "actions" :: {action: Model}

          Optional keys: "allowtrun" :: Bool

          Meaning: first argument must be one of keys from "actions"

                   dictionary. Other arguments must be valid models. Key 

                   "allowtrun" denies or allows (default: allow) reducing 

                   action names. For example, if there are actions “start”, 

                   “stop” and “restart” then if reducing is allowed “start” 

                   may be reduced to “sta”, “stop” to “sto” and “restart” to 



aslist    Required keys: "check" :: ArgTrans

          Meaning: check argument list as a single argument


2.4. Transformations                                             chk-trans

Every ArgTrans is either a dictionary or a Check. If it is a Check, then 

argument is not transformed, only checked. If it is a dictionary it may 

contain the following keys:

Key     Value and description

check   Check

        Check the argument.

trans   Transformation

        Transform the argument using transformation. Every transformation is 

        a list of two elemnts: name of the transformation and argument. 

        Possible transformations:

        Name    {transargument}

        eq      a (any value)

                Return 1 if {argument} is identical to {transargument} and 

                0 otherwise.

        func    Function (a -> b) (function that takes one argument)

                Pass the argument to the function and use the result.

        eval    String (expression)

                Eval the {transargument} and take the result. Inside the 

                expression a:Arg is {argument} and a:Trans is 


        earg    _ (argument is ignored)

                Eval the being transformed argument and take the result. Note 

                that {transargument} is still available via a:Trans 


        call    [{functionarguments}] (list of function arguments)

                Take the result of call({argument}{transargument}, {}).

        pipe    [ Transformation ] (list of transformations)

                Take the result of n'th transformation and transform it using 

                the (n+1)'th transformation.

transchk  Check

        Check the result of transformation.

skip    _ (value is ignored)

        Do not add {argument} to the arguments list.


3. Example usage                                                 chk-usage

Pretend that you want to create a function that will echo message with changed 

highlighting and want to throw an exception if given higlight group does not 

exist: >

    " Tests, whether given highlight group exists

    function HighlightExists(hlname)


            silent execute "highlight ".a:name

            return 1


            return 0



    " Get a dictionary with this plugins' functions

    let s:chkdict=load#LoadFuncdict().getfunctions("chk")

    function EchoHighlighted(hlname, text)

        " Test, whether given ``hlname'' is a valid name for a highlight group 

        " and this highlight group exists.

        if !s:chkdict.checkargument(["and", [["regex", '^[a-zA-Z0-9_]\+$', "Invalid name for highlight group"],

                                            \["func", function("HighlightExists"), "Highlight group does not exist"]]],


            throw "Invalid hlname."


        execute "echohl ".a:hlname

        echo a:text

        echohl None


Now, if you do >

    call EchoHighlighted("Comment", "This message will be highlighted like a comment")

you will get highlighted message, but these calls will throw an error: >

    call EchoHighlighted("Invalid Name", "This will throw an error")

    " output:

    " chk/achk.regex:InvalidValue(Value does not match regular expression /'^[a-zA-Z0-9_]\+$'/: 'Invalid Name')

    " chk/achk._main:InvalidValue(Invalid name for highlight group)

    " chk/achk._main:InvalidValue(Invalid value)

    " Error detected while processing function EchoHighlighted:

    " line    6:

    " E605: Exception not caught: Invalid hlname.

    call EchoHighlighted("NonExistantGroup", "This will throw an error too")

    " output:

    " chk/achk.func:InvalidValue(Function function('HighlightExists') returned a error)

    " chk/achk._main:InvalidValue(Highlight group does not exist)

    " chk/achk._main:InvalidValue(Invalid value)

    " Error detected while processing function EchoHighlighted:

    " line    6:

    " E605: Exception not caught: Invalid hlname.

Here is the same example, rewritten to use checkarguments function and new 

`hlgroup' check: >

    " Get a dictionary with this plugins' functions

    let s:chkdict=load#LoadFuncdict().getfunctions("chk")

    function EchoHighlighted(...)

        " Test, whether given ``hlname'' is a valid name for a highlight group 

        " and this highlight group exists.

        let args=s:chkdict.checkarguments({"model": "simple",

                \"required": [["hlgroup", ""],

                             \["any", ""]],}


        if type(args)!=type([])

            throw "Invalid arguments."


        execute "echohl ".args[0]

        echo args[1]

        echohl None


vim: ft=help:tw=78:nowrap