(declare (indent 1) (debug t))
(cons 'if (cons cond (cons nil body))))
+(defvar --dolist-tail-- nil
+ "Temporary variable used in `dolist' expansion.")
+
(defmacro dolist (spec &rest body)
"Loop over a list.
Evaluate BODY with VAR bound to each car from LIST, in turn.
\(fn (VAR LIST [RESULT]) BODY...)"
(declare (indent 1) (debug ((symbolp form &optional form) body)))
- (let ((temp (make-symbol "--dolist-temp--")))
+ ;; It would be cleaner to create an uninterned symbol,
+ ;; but that uses a lot more space when many functions in many files
+ ;; use dolist.
+ (let ((temp '--dolist-tail--))
`(let ((,temp ,(nth 1 spec))
,(car spec))
(while ,temp
(setq ,(car spec) (car ,temp))
- (setq ,temp (cdr ,temp))
- ,@body)
+ ,@body
+ (setq ,temp (cdr ,temp)))
,@(if (cdr (cdr spec))
`((setq ,(car spec) nil) ,@(cdr (cdr spec)))))))
+(defvar --dotimes-limit-- nil
+ "Temporary variable used in `dotimes' expansion.")
+
(defmacro dotimes (spec &rest body)
"Loop a certain number of times.
Evaluate BODY with VAR bound to successive integers running from 0,
\(fn (VAR COUNT [RESULT]) BODY...)"
(declare (indent 1) (debug dolist))
- (let ((temp (make-symbol "--dotimes-temp--"))
+ ;; It would be cleaner to create an uninterned symbol,
+ ;; but that uses a lot more space when many functions in many files
+ ;; use dotimes.
+ (let ((temp '--dotimes-limit--)
(start 0)
(end (nth 1 spec)))
`(let ((,temp ,end)
(kill-local-variable hook)
(set hook hook-value))))))
-(defun add-to-list (list-var element &optional append)
+(defun add-to-list (list-var element &optional append compare-fn)
"Add ELEMENT to the value of LIST-VAR if it isn't there yet.
-The test for presence of ELEMENT is done with `equal'.
+The test for presence of ELEMENT is done with `equal',
+or with COMPARE-FN if that's non-nil.
If ELEMENT is added, it is added at the beginning of the list,
unless the optional argument APPEND is non-nil, in which case
ELEMENT is added at the end.
into a hook function that will be run only after loading the package.
`eval-after-load' provides one way to do this. In some cases
other hooks, such as major mode hooks, can do the job."
- (if (member element (symbol-value list-var))
+ (if (if compare-fn
+ (let (present)
+ (dolist (elt (symbol-value list-var))
+ (if (funcall compare-fn element elt)
+ (setq present t)))
+ present)
+ (member element (symbol-value list-var)))
(symbol-value list-var)
(set list-var
(if append
(sit-for 1)
t)))
n))
+
+(defun sit-for (seconds &optional nodisp obsolete)
+ "Perform redisplay, then wait for SECONDS seconds or until input is available.
+SECONDS may be a floating-point value.
+\(On operating systems that do not support waiting for fractions of a
+second, floating-point values are rounded down to the nearest integer.)
+
+If optional arg NODISP is t, don't redisplay, just wait for input.
+Redisplay does not happen if input is available before it starts.
+
+Value is t if waited the full time with no input arriving, and nil otherwise.
+
+An obsolete, but still supported form is
+\(sit-for SECONDS &optional MILLISECONDS NODISP)
+where the optional arg MILLISECONDS specifies an additional wait period,
+in milliseconds; this was useful when Emacs was built without
+floating point support.
+
+\(fn SECONDS &optional NODISP)"
+ (when (or obsolete (numberp nodisp))
+ (setq seconds (+ seconds (* 1e-3 nodisp)))
+ (setq nodisp obsolete))
+ (cond
+ (noninteractive
+ (sleep-for seconds)
+ t)
+ ((input-pending-p)
+ nil)
+ ((<= seconds 0)
+ (or nodisp (redisplay)))
+ (t
+ (or nodisp (redisplay))
+ (let ((read (read-event nil nil seconds)))
+ (or (null read)
+ (progn (push read unread-command-events)
+ nil))))))
\f
;;; Atomic change groups.
`(with-local-quit
(catch ',catch-sym
(let ((throw-on-input ',catch-sym))
- (or (not (sit-for 0 0 t))
- ,@body))))))
+ (or (input-pending-p)
+ ,@body))))))
(defmacro combine-after-change-calls (&rest body)
"Execute BODY, but don't call the after-change functions till the end.
(defun looking-back (regexp &optional limit greedy)
"Return non-nil if text before point matches regular expression REGEXP.
Like `looking-at' except matches before point, and is slower.
-LIMIT if non-nil speeds up the search by specifying how far back the
-match can start.
+LIMIT if non-nil speeds up the search by specifying a minimum
+starting position, to avoid checking matches that would start
+before LIMIT.
If GREEDY is non-nil, extend the match backwards as far as possible,
stopping when a single additional previous character cannot be part