Consider:
lintr::lint("`%%`(x, y)\n", lintr::undesirable_operator_linter(c("%%" = NA)))
This doesn't throw a lint because %% is a call, not an operator. But it seems reasonable to expect this code to lint (perhaps optionally), e.g. if I'm a package developer trying to deprecate my old %old-grapes% in favor of %new-grapes%. Then any usage of the old function should be pointed out if I'm offering a tool for my downstreams to self-diagnose their exposure.
Of course, we could use undesirable_function_linter(c("%%" = NA)) (well, actually it seems there's a bug there), but users needn't think of that.