summaryrefslogtreecommitdiff
path: root/lisp/subr.el
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2013-07-06 23:18:58 -0600
committerTom Tromey <tromey@redhat.com>2013-07-06 23:18:58 -0600
commit6dacdad5fcb278e5a16b38bb81786aac9ca27be4 (patch)
treef5f331ea361ba0f99e0f9b638d183ad492a7da31 /lisp/subr.el
parent0a6f2ff0c8ceb29703e76cddd46ea3f176dd873a (diff)
parent219afb88d9d484393418820d1c08dc93299110ec (diff)
downloademacs-6dacdad5fcb278e5a16b38bb81786aac9ca27be4.tar.gz
merge from trunk
this merges frmo trunk and fixes various build issues. this needed a few ugly tweaks. this hangs in "make check" now
Diffstat (limited to 'lisp/subr.el')
-rw-r--r--lisp/subr.el198
1 files changed, 115 insertions, 83 deletions
diff --git a/lisp/subr.el b/lisp/subr.el
index 6f46e1189cf..b2918baf247 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1206,6 +1206,11 @@ is converted into a string by expressing it in decimal."
(declare (obsolete make-hash-table "22.1"))
(make-hash-table :test (or test 'eql)))
+(defun log10 (x)
+ "Return (log X 10), the log base 10 of X."
+ (declare (obsolete log "24.4"))
+ (log x 10))
+
;; These are used by VM and some old programs
(defalias 'focus-frame 'ignore "")
(make-obsolete 'focus-frame "it does nothing." "22.1")
@@ -1985,20 +1990,14 @@ for numeric input."
or the octal character code.
RET terminates the character code and is discarded;
any other non-digit terminates the character code and is then used as input."))
- (setq char (read-event (and prompt (format "%s-" prompt)) t))
+ (setq translated (read-key (and prompt (format "%s-" prompt))))
(if inhibit-quit (setq quit-flag nil)))
- ;; Translate TAB key into control-I ASCII character, and so on.
- ;; Note: `read-char' does it using the `ascii-character' property.
- ;; We should try and use read-key instead.
- (let ((translation (lookup-key local-function-key-map (vector char))))
- (setq translated (if (arrayp translation)
- (aref translation 0)
- char)))
(if (integerp translated)
(setq translated (char-resolve-modifiers translated)))
(cond ((null translated))
((not (integerp translated))
- (setq unread-command-events (list char)
+ (setq unread-command-events
+ (listify-key-sequence (this-single-command-raw-keys))
done t))
((/= (logand translated ?\M-\^@) 0)
;; Turn a meta-character into a character with the 0200 bit set.
@@ -2017,7 +2016,8 @@ any other non-digit terminates the character code and is then used as input."))
((and (not first) (eq translated ?\C-m))
(setq done t))
((not first)
- (setq unread-command-events (list char)
+ (setq unread-command-events
+ (listify-key-sequence (this-single-command-raw-keys))
done t))
(t (setq code translated
done t)))
@@ -2181,6 +2181,7 @@ An obsolete, but still supported form is
where the optional arg MILLISECONDS specifies an additional wait period,
in milliseconds; this was useful when Emacs was built without
floating point support."
+ (declare (advertised-calling-convention (seconds &optional nodisp) "22.1"))
(if (numberp nodisp)
(setq seconds (+ seconds (* 1e-3 nodisp))
nodisp obsolete)
@@ -2195,7 +2196,10 @@ floating point support."
(or nodisp (redisplay)))
(t
(or nodisp (redisplay))
- (let ((read (read-event nil nil seconds)))
+ ;; FIXME: we should not read-event here at all, because it's much too
+ ;; difficult to reliably "undo" a read-event by pushing it onto
+ ;; unread-command-events.
+ (let ((read (read-event nil t seconds)))
(or (null read)
(progn
;; If last command was a prefix arg, e.g. C-u, push this event onto
@@ -2205,7 +2209,6 @@ floating point support."
(setq read (cons t read)))
(push read unread-command-events)
nil))))))
-(set-advertised-calling-convention 'sit-for '(seconds &optional nodisp) "22.1")
(defun y-or-n-p (prompt)
"Ask user a \"y or n\" question. Return t if answer is \"y\".
@@ -2235,7 +2238,8 @@ is nil and `use-dialog-box' is non-nil."
(cond
(noninteractive
(setq prompt (concat prompt
- (if (eq ?\s (aref prompt (1- (length prompt))))
+ (if (or (zerop (length prompt))
+ (eq ?\s (aref prompt (1- (length prompt)))))
"" " ")
"(y or n) "))
(let ((temp-prompt prompt))
@@ -2252,7 +2256,8 @@ is nil and `use-dialog-box' is non-nil."
(x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip)))))
(t
(setq prompt (concat prompt
- (if (eq ?\s (aref prompt (1- (length prompt))))
+ (if (or (zerop (length prompt))
+ (eq ?\s (aref prompt (1- (length prompt)))))
"" " ")
"(y or n) "))
(while
@@ -2444,11 +2449,12 @@ If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
(recenter (/ (window-height) 2))))
(message (or message "Type %s to continue editing.")
(single-key-description exit-char))
- (let ((event (read-event)))
+ (let ((event (read-key)))
;; `exit-char' can be an event, or an event description list.
(or (eq event exit-char)
(eq event (event-convert-list exit-char))
- (setq unread-command-events (list event)))))
+ (setq unread-command-events
+ (append (this-single-command-raw-keys))))))
(delete-overlay ol))))
@@ -3729,6 +3735,8 @@ Return nil if there isn't one."
(defun eval-after-load (file form)
"Arrange that if FILE is loaded, FORM will be run immediately afterwards.
If FILE is already loaded, evaluate FORM right now.
+FORM can be an Elisp expression (in which case it's passed to `eval'),
+or a function (in which case it's passed to `funcall' with no argument).
If a matching file is loaded again, FORM will be evaluated again.
@@ -3756,43 +3764,61 @@ Usually FILE is just a library name like \"font-lock\" or a feature name
like 'font-lock.
This function makes or adds to an entry on `after-load-alist'."
+ (declare (compiler-macro
+ (lambda (whole)
+ (if (eq 'quote (car-safe form))
+ ;; Quote with lambda so the compiler can look inside.
+ `(eval-after-load ,file (lambda () ,(nth 1 form)))
+ whole))))
;; Add this FORM into after-load-alist (regardless of whether we'll be
;; evaluating it now).
(let* ((regexp-or-feature
(if (stringp file)
(setq file (purecopy (load-history-regexp file)))
file))
- (elt (assoc regexp-or-feature after-load-alist)))
+ (elt (assoc regexp-or-feature after-load-alist))
+ (func
+ (if (functionp form) form
+ ;; Try to use the "current" lexical/dynamic mode for `form'.
+ (eval `(lambda () ,form) lexical-binding))))
(unless elt
(setq elt (list regexp-or-feature))
(push elt after-load-alist))
- ;; Make sure `form' is evalled in the current lexical/dynamic code.
- (setq form `(funcall ',(eval `(lambda () ,form) lexical-binding)))
;; Is there an already loaded file whose name (or `provide' name)
;; matches FILE?
(prog1 (if (if (stringp file)
(load-history-filename-element regexp-or-feature)
(featurep file))
- (eval form))
- (when (symbolp regexp-or-feature)
- ;; For features, the after-load-alist elements get run when `provide' is
- ;; called rather than at the end of the file. So add an indirection to
- ;; make sure that `form' is really run "after-load" in case the provide
- ;; call happens early.
- (setq form
- `(if load-file-name
- (let ((fun (make-symbol "eval-after-load-helper")))
- (fset fun `(lambda (file)
- (if (not (equal file ',load-file-name))
- nil
- (remove-hook 'after-load-functions ',fun)
- ,',form)))
- (add-hook 'after-load-functions fun))
- ;; Not being provided from a file, run form right now.
- ,form)))
- ;; Add FORM to the element unless it's already there.
- (unless (member form (cdr elt))
- (nconc elt (list form))))))
+ (funcall func))
+ (let ((delayed-func
+ (if (not (symbolp regexp-or-feature)) func
+ ;; For features, the after-load-alist elements get run when
+ ;; `provide' is called rather than at the end of the file.
+ ;; So add an indirection to make sure that `func' is really run
+ ;; "after-load" in case the provide call happens early.
+ (lambda ()
+ (if (not load-file-name)
+ ;; Not being provided from a file, run func right now.
+ (funcall func)
+ (let ((lfn load-file-name)
+ ;; Don't use letrec, because equal (in
+ ;; add/remove-hook) would get trapped in a cycle.
+ (fun (make-symbol "eval-after-load-helper")))
+ (fset fun (lambda (file)
+ (when (equal file lfn)
+ (remove-hook 'after-load-functions fun)
+ (funcall func))))
+ (add-hook 'after-load-functions fun)))))))
+ ;; Add FORM to the element unless it's already there.
+ (unless (member delayed-func (cdr elt))
+ (nconc elt (list delayed-func)))))))
+
+(defmacro with-eval-after-load (file &rest body)
+ "Execute BODY after FILE is loaded.
+FILE is normally a feature name, but it can also be a file name,
+in case that file does not provide any feature."
+ (declare (indent 1) (debug t))
+ `(eval-after-load ,file (lambda () ,@body)))
(defvar after-load-functions nil
"Special hook run after loading a file.
@@ -3804,12 +3830,11 @@ name of the file just loaded.")
ABS-FILE, a string, should be the absolute true name of a file just loaded.
This function is called directly from the C code."
;; Run the relevant eval-after-load forms.
- (mapc #'(lambda (a-l-element)
- (when (and (stringp (car a-l-element))
- (string-match-p (car a-l-element) abs-file))
- ;; discard the file name regexp
- (mapc #'eval (cdr a-l-element))))
- after-load-alist)
+ (dolist (a-l-element after-load-alist)
+ (when (and (stringp (car a-l-element))
+ (string-match-p (car a-l-element) abs-file))
+ ;; discard the file name regexp
+ (mapc #'funcall (cdr a-l-element))))
;; Complain when the user uses obsolete files.
(when (string-match-p "/obsolete/[^/]*\\'" abs-file)
(run-with-timer 0 nil
@@ -4234,7 +4259,25 @@ use `called-interactively-p'."
(declare (obsolete called-interactively-p "23.2"))
(called-interactively-p 'interactive))
-(defun set-temporary-overlay-map (map &optional keep-pred)
+(defun internal-push-keymap (keymap symbol)
+ (let ((map (symbol-value symbol)))
+ (unless (memq keymap map)
+ (unless (memq 'add-keymap-witness (symbol-value symbol))
+ (setq map (make-composed-keymap nil (symbol-value symbol)))
+ (push 'add-keymap-witness (cdr map))
+ (set symbol map))
+ (push keymap (cdr map)))))
+
+(defun internal-pop-keymap (keymap symbol)
+ (let ((map (symbol-value symbol)))
+ (when (memq keymap map)
+ (setf (cdr map) (delq keymap (cdr map))))
+ (let ((tail (cddr map)))
+ (and (or (null tail) (keymapp tail))
+ (eq 'add-keymap-witness (nth 1 map))
+ (set symbol tail)))))
+
+(defun set-temporary-overlay-map (map &optional keep-pred on-exit)
"Set MAP as a temporary keymap taking precedence over most other keymaps.
Note that this does NOT take precedence over the \"overriding\" maps
`overriding-terminal-local-map' and `overriding-local-map' (or the
@@ -4244,29 +4287,32 @@ found in MAP, the normal key lookup sequence then continues.
Normally, MAP is used only once. If the optional argument
KEEP-PRED is t, MAP stays active if a key from MAP is used.
KEEP-PRED can also be a function of no arguments: if it returns
-non-nil then MAP stays active."
- (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map"))
- (overlaysym (make-symbol "t"))
- (alist (list (cons overlaysym map)))
- (clearfun
- ;; FIXME: Use lexical-binding.
- `(lambda ()
- (unless ,(cond ((null keep-pred) nil)
- ((eq t keep-pred)
- `(eq this-command
- (lookup-key ',map
- (this-command-keys-vector))))
- (t `(funcall ',keep-pred)))
- (set ',overlaysym nil) ;Just in case.
- (remove-hook 'pre-command-hook ',clearfunsym)
- (setq emulation-mode-map-alists
- (delq ',alist emulation-mode-map-alists))))))
- (set overlaysym overlaysym)
- (fset clearfunsym clearfun)
- (add-hook 'pre-command-hook clearfunsym)
- ;; FIXME: That's the keymaps with highest precedence, except for
- ;; the `keymap' text-property ;-(
- (push alist emulation-mode-map-alists)))
+non-nil then MAP stays active.
+
+Optional ON-EXIT argument is a function that is called after the
+deactivation of MAP."
+ (let ((clearfun (make-symbol "clear-temporary-overlay-map")))
+ ;; Don't use letrec, because equal (in add/remove-hook) would get trapped
+ ;; in a cycle.
+ (fset clearfun
+ (lambda ()
+ ;; FIXME: Handle the case of multiple temporary-overlay-maps
+ ;; E.g. if isearch and C-u both use temporary-overlay-maps, Then
+ ;; the lifetime of the C-u should be nested within the isearch
+ ;; overlay, so the pre-command-hook of isearch should be
+ ;; suspended during the C-u one so we don't exit isearch just
+ ;; because we hit 1 after C-u and that 1 exits isearch whereas it
+ ;; doesn't exit C-u.
+ (unless (cond ((null keep-pred) nil)
+ ((eq t keep-pred)
+ (eq this-command
+ (lookup-key map (this-command-keys-vector))))
+ (t (funcall keep-pred)))
+ (remove-hook 'pre-command-hook clearfun)
+ (internal-pop-keymap map 'overriding-terminal-local-map)
+ (when on-exit (funcall on-exit)))))
+ (add-hook 'pre-command-hook clearfun)
+ (internal-push-keymap map 'overriding-terminal-local-map)))
;;;; Progress reporters.
@@ -4449,20 +4495,6 @@ convenience wrapper around `make-progress-reporter' and friends.
nil ,@(cdr (cdr spec)))))
-;;;; Support for watching filesystem events.
-
-(defun file-notify-handle-event (event)
- "Handle file system monitoring event.
-If EVENT is a filewatch event, call its callback.
-Otherwise, signal a `filewatch-error'."
- (interactive "e")
- (if (and (eq (car event) 'file-notify)
- (>= (length event) 3))
- (funcall (nth 2 event) (nth 1 event))
- (signal 'filewatch-error
- (cons "Not a valid file-notify event" event))))
-
-
;;;; Comparing version strings.
(defconst version-separator "."