rules:
rule-configurations:
    #
    # This is the default value (as of the time I wrote this) but I'm making
    # it explicit since it needs to agree with the value used by clang-format.
    # Thus, if we ever change the fish style to allow longer or shorter lines
    # this should be changed (as well as the corresponding .clang-format file).
    #
    - key: LONG_LINE
      value: 100
    #
    # The default limit for the length of variable names is 20. Long names are
    # problematic but twenty chars results in way too many errors. So increase
    # the limit to something more reasonable.
    #
    - key: LONG_VARIABLE_NAME
      value: 30
    #
    # This allows us to avoid peppering our code with inline comments such as
    #
    #   scoped_lock locker(m_lock);  //!OCLINT(side-effect)
    #
    # Specifically, this config key tells oclint that the named classes have
    # RAII behavior so the local vars are actually used.
    #
    - key: RAII_CUSTOM_CLASSES
      value: scoped_lock scoped_buffer_t builtin_commandline_scoped_transient_t scoped_push

    # We're slightly more persmissive regarding the total number of lines in a
    # function. Default is 50.
    - key: LONG_METHOD
      value: 60

    # We're slightly more persmissive regarding the number of non-comment
    # lines in a function. Default is 30.
    - key: NCSS_METHOD
      value: 40

    # We're willing to allow slighly more linearly independent paths through a
    # function. Most of our code has a lot of `switch` blocks or consecutive
    # `if` tests that are straightforward to interpret but which increase this
    # metric. Default is 10.
    - key: CYCLOMATIC_COMPLEXITY
      value: 14

    # We're willing to allow slighly more execution paths through a function.
    # Default is 200.
    - key: NPATH_COMPLEXITY
      value: 300

disable-rules:
    #
    # A few instances of "useless parentheses" errors are meaningful. Mostly
    # in the context of the `return` statement. Unfortunately the vast
    # majority would result in removing parentheses that decreases
    # readability. So we're going to ignore this warning and rely on humans to
    # notice when the parentheses are truly not needed.
    #
    # Also, some macro expansions, such as FD_SET(), trigger this warning and
    # we don't want to suppress each of those individually.
    #
    - UselessParentheses
    #
    # OCLint wants variable names to be at least three characters in length.
    # Which would be fine if it supported a reasonable set of exceptions
    # (e.g., "i", "j", "k") and allowed adding additional exceptions to match
    # conventions employed by a project. Since it doesn't, and thus generates
    # a lot of really annoying warnings, we're going to disable this rule.
    #
    - ShortVariableName
    #
    # This rule flags perfectly reasonable conditions like `if (!some_condition)`
    # and is therefore just noise. Disable this rule.
    #
    - InvertedLogic
    #
    # The idea behind the "double negative" rule is sound since constructs
    # like "!!(var & flag)" should be written as "static_cast<bool>(var &
    # flag)". Unfortunately this rule has way too many false positives;
    # especially in the context of assert statements. So disable this rule.
    #
    - DoubleNegative
    #
    # Avoiding bitwise operators in a conditional is a good idea with one
    # exception: testing whether a bit flag is set. Which happens to be the
    # only time you'll see something like `if (j->flags & JOB_CONSTRUCTED)`
    # in fish source.
    #
    - BitwiseOperatorInConditional
