How can I extend a cl-defmethod to match on multiple major-modes? There is a little documentation in cl-generic, but I don't understand what is going on with the generalizer macros.
As an example,
(cl-defgeneric my-gen-fun (arg)
(message "%S" arg))
;; define this so it wouldn't affect other cc-derived modes, eg. java, awk, etc.
(cl-defmethod my-gen-fun (&context (major-mode c-mode c++-mode) arg)
(message "c-%S" arg))
I would want (my-gen-fun arg) to only print "c-" in both c-mode and c++-mode, but not other cc-derived modes like java-mode or awk-mode. How can I add a new specializer to handle this case?
The
&contextis like%optionalin that it applies too all the subsequent args, so it has to come after the arguments.But the
(major-mode <foo>-mode)thingy does not extend to(major-mode <foo>-mode <bar>-mode)like you suggest (although it admittedly would be a natural extension). So instead you have to callcl-defmethodtwice. If the body is large, you shoud probably put it into a separate function:I do have a local patch to
cl-generic.elwhich adds the "multiple major modes" functionality you suggest, but after reviewing it I see that it's kind of a hack and introduces various corner-case problems.Some of the corner case problems are related to the fact that CLOS does not offer something like
ororandspecializers like:this is because it can make it "impossible" to find a sound ordering of the applicable methods (e.g.,is the above specializer more or less specific than
(x list)or(x (or (eql 5) cons))?).