- (if (or local
- ;; Detect the case where make-local-variable was used on a hook
- ;; and do what we used to do.
- (and (local-variable-p hook (current-buffer))
- (not (memq t (symbol-value hook)))))
- (let ((hook-value (symbol-value hook)))
- (if (and (consp hook-value) (not (functionp hook-value)))
- (if (member function hook-value)
- (setq hook-value (delete function (copy-sequence hook-value))))
- (if (equal hook-value function)
- (setq hook-value nil)))
- (set hook hook-value))
- (let ((hook-value (default-value hook)))
- (if (and (consp hook-value) (not (functionp hook-value)))
- (if (member function hook-value)
- (setq hook-value (delete function (copy-sequence hook-value))))
- (if (equal hook-value function)
- (setq hook-value nil)))
- (set-default hook hook-value)))))
-
-(defun add-to-list (list-var element)
+ (flet ((hook-remove
+ (function hook-value)
+ (flet ((hook-test
+ (fn hel)
+ (or (equal fn hel)
+ (and (symbolp hel)
+ (equal fn
+ (get hel 'one-shot-hook-fun))))))
+ (if (and (consp hook-value)
+ (not (functionp hook-value)))
+ (if (member* function hook-value :test 'hook-test)
+ (setq hook-value
+ (delete* function (copy-sequence hook-value)
+ :test 'hook-test)))
+ (if (equal hook-value function)
+ (setq hook-value nil)))
+ hook-value)))
+ (if (or local
+ ;; Detect the case where make-local-variable was used on a hook
+ ;; and do what we used to do.
+ (and (local-variable-p hook (current-buffer))
+ (not (memq t (symbol-value hook)))))
+ (set hook (hook-remove function (symbol-value hook)))
+ (set-default hook (hook-remove function (default-value hook)))))))
+
+;; XEmacs addition
+;; #### we need a coherent scheme for indicating compatibility info,
+;; so that it can be programmatically retrieved.
+(defun add-local-hook (hook function &optional append)
+ "Add to the local value of HOOK the function FUNCTION.
+This modifies only the buffer-local value for the hook (which is
+automatically make buffer-local, if necessary), not its default value.
+FUNCTION is not added if already present.
+FUNCTION is added (if necessary) at the beginning of the hook list
+unless the optional argument APPEND is non-nil, in which case
+FUNCTION is added at the end.
+
+HOOK should be a symbol, and FUNCTION may be any valid function. If
+HOOK is void, it is first set to nil. If HOOK's value is a single
+function, it is changed to a list of functions.
+
+You can remove this hook yourself using `remove-local-hook'.
+
+See also `add-hook' and `make-local-hook'."
+ (make-local-hook hook)
+ (add-hook hook function append t))
+
+;; XEmacs addition
+(defun remove-local-hook (hook function)
+ "Remove from the local value of HOOK the function FUNCTION.
+This modifies only the buffer-local value for the hook, not its default
+value. (Nothing happens if the hook is not buffer-local.)
+HOOK should be a symbol, and FUNCTION may be any valid function. If
+FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
+list of hooks to run in HOOK, then nothing is done. See `add-hook'.
+
+See also `add-local-hook' and `make-local-hook'."
+ (if (local-variable-p hook (current-buffer))
+ (remove-hook hook function t)))
+
+(defun add-one-shot-hook (hook function &optional append local)
+ "Add to the value of HOOK the one-shot function FUNCTION.
+FUNCTION will automatically be removed from the hook the first time
+after it runs (whether to completion or to an error).
+FUNCTION is not added if already present.
+FUNCTION is added (if necessary) at the beginning of the hook list
+unless the optional argument APPEND is non-nil, in which case
+FUNCTION is added at the end.
+
+HOOK should be a symbol, and FUNCTION may be any valid function. If
+HOOK is void, it is first set to nil. If HOOK's value is a single
+function, it is changed to a list of functions.
+
+You can remove this hook yourself using `remove-hook'.
+
+See also `add-hook', `add-local-hook', and `add-local-one-shot-hook'."
+ (let ((sym (gensym)))
+ (fset sym `(lambda (&rest args)
+ (unwind-protect
+ (apply ',function args)
+ (remove-hook ',hook ',sym ',local))))
+ (put sym 'one-shot-hook-fun function)
+ (add-hook hook sym append local)))
+
+(defun add-local-one-shot-hook (hook function &optional append)
+ "Add to the local value of HOOK the one-shot function FUNCTION.
+FUNCTION will automatically be removed from the hook the first time
+after it runs (whether to completion or to an error).
+FUNCTION is not added if already present.
+FUNCTION is added (if necessary) at the beginning of the hook list
+unless the optional argument APPEND is non-nil, in which case
+FUNCTION is added at the end.
+
+The optional fourth argument, LOCAL, if non-nil, says to modify
+the hook's buffer-local value rather than its default value.
+This makes no difference if the hook is not buffer-local.
+To make a hook variable buffer-local, always use
+`make-local-hook', not `make-local-variable'.
+
+HOOK should be a symbol, and FUNCTION may be any valid function. If
+HOOK is void, it is first set to nil. If HOOK's value is a single
+function, it is changed to a list of functions.
+
+You can remove this hook yourself using `remove-local-hook'.
+
+See also `add-hook', `add-local-hook', and `add-local-one-shot-hook'."
+ (make-local-hook hook)
+ (add-one-shot-hook hook function append t))
+
+(defun add-to-list (list-var element &optional append)