;;; subr.el --- basic lisp subroutines for Emacs
-;; Copyright (C) 1985, 86, 92, 94, 95, 99, 2000, 2001, 2002, 2003
+;; Copyright (C) 1985, 86, 92, 94, 95, 99, 2000, 2001, 2002, 03, 2004
;; Free Software Foundation, Inc.
;; Maintainer: FSF
x))))
(defun delete-dups (list)
- "Destructively return LIST, with `equal' duplicates removed.
-LIST must be a proper list. The value of LIST after a call to
-this function is undefined. Use \(setq LIST (delete-dups LIST))
-if you want to store the return value in LIST. Of several
-`equal' occurrences of an element in LIST, the last one is kept."
- (while (member (car list) (cdr list))
- (pop list))
+ "Destructively remove `equal' duplicates from LIST.
+Store the result in LIST and return it. LIST must be a proper list.
+Of several `equal' occurrences of an element in LIST, the first
+one is kept."
(let ((tail list))
(while tail
- (while (member (cadr tail) (cddr tail))
- (setcdr tail (cddr tail)))
- (pop tail)))
+ (setcdr tail (delete (car tail) (cdr tail)))
+ (setq tail (cdr tail))))
list)
(defun number-sequence (from &optional to inc)
(defsubst event-start (event)
"Return the starting position of EVENT.
-If EVENT is a mouse press or a mouse click, this returns the location
+If EVENT is a mouse or key press or a mouse click, this returns the location
of the event.
If EVENT is a drag, this returns the drag's starting position.
The return value is of the form
(list (selected-window) (point) '(0 . 0) 0)))
(defsubst event-end (event)
- "Return the ending location of EVENT. EVENT should be a click or drag event.
+ "Return the ending location of EVENT.
+EVENT should be a click, drag, or key press event.
If EVENT is a click event, this function is the same as `event-start'.
The return value is of the form
(WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
(car (nth 1 position))
(nth 1 position))))
+(defun posn-set-point (position)
+ "Move point to POSITION.
+Select the corresponding window as well."
+ (if (not (windowp (posn-window position)))
+ (error "Position not in text area of window"))
+ (select-window (posn-window position))
+ (if (numberp (posn-point position))
+ (goto-char (posn-point position))))
+
(defsubst posn-x-y (position)
"Return the x and y coordinates in POSITION.
POSITION should be a list of the form returned by the `event-start'
(setq pass new-pass))))))
(message nil)
(or pass default ""))))
+
+;; This should be used by `call-interactively' for `n' specs.
+(defun read-number (prompt &optional default)
+ (let ((n nil))
+ (when default
+ (setq prompt
+ (if (string-match "\\(\\):[^:]*" prompt)
+ (replace-match (format " [%s]" default) t t prompt 1)
+ (concat prompt (format " [%s] " default)))))
+ (while
+ (progn
+ (let ((str (read-from-minibuffer prompt nil nil nil nil
+ (number-to-string default))))
+ (setq n (cond
+ ((zerop (length str)) default)
+ ((stringp str) (read str)))))
+ (unless (numberp n)
+ (message "Please enter a number.")
+ (sit-for 1)
+ t)))
+ n))
\f
;;; Atomic change groups.
(subrp object) (byte-code-function-p object)
(eq (car-safe object) 'lambda)))
-(defun interactive-form (function)
- "Return the interactive form of FUNCTION.
-If function is a command (see `commandp'), value is a list of the form
-\(interactive SPEC). If function is not a command, return nil."
- (setq function (indirect-function function))
- (when (commandp function)
- (cond ((byte-code-function-p function)
- (when (> (length function) 5)
- (let ((spec (aref function 5)))
- (if spec
- (list 'interactive spec)
- (list 'interactive)))))
- ((subrp function)
- (subr-interactive-form function))
- ((eq (car-safe function) 'lambda)
- (setq function (cddr function))
- (when (stringp (car function))
- (setq function (cdr function)))
- (let ((form (car function)))
- (when (eq (car-safe form) 'interactive)
- (copy-sequence form)))))))
-
(defun assq-delete-all (key alist)
"Delete from ALIST all elements whose car is KEY.
Return the modified alist.