+(defun run-hook-with-args-until-success (hook &rest args)
+ "Run HOOK with the specified arguments ARGS.
+HOOK should be a symbol, a hook variable. Its value should
+be a list of functions. We call those functions, one by one,
+passing arguments ARGS to each of them, until one of them
+returns a non-nil value. Then we return that value.
+If all the functions return nil, we return nil.
+
+To make a hook variable buffer-local, use `make-local-hook', not
+`make-local-variable'."
+ (and (boundp hook)
+ (symbol-value hook)
+ (let ((value (symbol-value hook))
+ success)
+ (while (and value (not success))
+ (if (eq (car value) t)
+ ;; t indicates this hook has a local binding;
+ ;; it means to run the global binding too.
+ (let ((functions (default-value hook)))
+ (while (and functions (not success))
+ (setq success (apply (car functions) args))
+ (setq functions (cdr functions))))
+ (setq success (apply (car value) args)))
+ (setq value (cdr value)))
+ success)))
+
+(defun run-hook-with-args-until-failure (hook &rest args)
+ "Run HOOK with the specified arguments ARGS.
+HOOK should be a symbol, a hook variable. Its value should
+be a list of functions. We call those functions, one by one,
+passing arguments ARGS to each of them, until one of them
+returns nil. Then we return nil.
+If all the functions return non-nil, we return non-nil.
+
+To make a hook variable buffer-local, use `make-local-hook', not
+`make-local-variable'."
+ (and (boundp hook)
+ (symbol-value hook)
+ (let ((value (symbol-value hook))
+ (success t))
+ (while (and value success)
+ (if (eq (car value) t)
+ ;; t indicates this hook has a local binding;
+ ;; it means to run the global binding too.
+ (let ((functions (default-value hook)))
+ (while (and functions success)
+ (setq success (apply (car functions) args))
+ (setq functions (cdr functions))))
+ (setq success (apply (car value) args)))
+ (setq value (cdr value)))
+ success)))
+