\f
* Changes in Specialized Modes and Packages in Emacs 28.1
+** Macroexp
+---
+*** New function 'macroexp-file-name' to know the name of the current file
+---
+*** New function 'macroexp-compiling-p' to know if we're compiling.
+
** 'blink-cursor-mode' is now enabled by default regardless of the UI.
It used to be enabled when Emacs is started in GUI mode but not when started
in text mode. The cursor still only actually blinks in GUI frames.
(when (and (mode-local--function-overload-p newfn)
(not (mode-local--overload-obsoleted-by newfn))
;; Only throw this warning when byte compiling things.
- (boundp 'byte-compile-current-file)
- byte-compile-current-file
- (not (string-match "cedet" byte-compile-current-file))
+ (macroexp-compiling-p)
+ (not (string-match "cedet" (macroexp-file-name)))
)
(make-obsolete-overload oldfnalias newfn when)
(byte-compile-warn
"%s: `%s' obsoletes overload `%s'"
- byte-compile-current-file
+ (macroexp-file-name)
newfn
(with-suppressed-warnings ((obsolete semantic-overload-symbol-from-function))
(semantic-overload-symbol-from-function oldfnalias)))))
(defvaralias oldvaralias newvar)
(error
;; Only throw this warning when byte compiling things.
- (when (and (boundp 'byte-compile-current-file)
- byte-compile-current-file)
+ (when (macroexp-compiling-p)
(byte-compile-warn
"variable `%s' obsoletes, but isn't alias of `%s'"
newvar oldvaralias)
'(with-current-buffer (wisent-log-buffer)
(erase-buffer)))
-(defvar byte-compile-current-file)
-
(defun wisent-source ()
"Return the current source file name or nil."
- (let ((source (or (and (boundp 'byte-compile-current-file)
- byte-compile-current-file)
- load-file-name (buffer-file-name))))
+ (let ((source (macroexp-file-name)))
(if source
(file-relative-name source))))
;; output warnings.
(and src
(intern (format "wisent-%s--expected-conflicts"
- (replace-regexp-in-string "\\.el$" "" src))))))
+ (replace-regexp-in-string "\\.el\\'" "" src))))))
(when (or (not (zerop rrc-total))
(and (not (zerop src-total))
(not (= src-total (or wisent-expected-conflicts 0)))
;; for optional functionality
(require 'python nil t)
-;; Tell wisent how many shift/reduce conflicts are to be expected by
-;; this grammar.
-(eval-and-compile
- (defconst wisent-python--expected-conflicts 4))
-
(require 'semantic/wisent)
(require 'semantic/wisent/python-wy)
(require 'semantic/find)
;; (byte-compile-generate-emacs19-bytecodes
;; byte-compile-generate-emacs19-bytecodes)
(byte-compile-warnings byte-compile-warnings)
+ ;; Indicate that we're not currently loading some file.
+ ;; This is used in `macroexp-file-name' to make sure that
+ ;; loading file A which does (byte-compile-file B) won't
+ ;; cause macro calls in B to think they come from A.
+ (load-file-name nil)
)
,@body))
;;; Declarations.
-(defvar cl--compiling-file nil)
-(defun cl--compiling-file ()
- (or cl--compiling-file
- (and (boundp 'byte-compile--outbuffer)
- (bufferp (symbol-value 'byte-compile--outbuffer))
- (equal (buffer-name (symbol-value 'byte-compile--outbuffer))
- " *Compiler Output*"))))
+(define-obsolete-function-alias 'cl--compiling-file
+ #'macroexp-compiling-p "28.1")
(defvar cl--proclaims-deferred nil)
Puts `(cl-eval-when (compile load eval) ...)' around the declarations
so that they are registered at compile-time as well as run-time."
(let ((body (mapcar (lambda (x) `(cl-proclaim ',x)) specs)))
- (if (cl--compiling-file) `(cl-eval-when (compile load eval) ,@body)
+ (if (macroexp-compiling-p) `(cl-eval-when (compile load eval) ,@body)
`(progn ,@body)))) ; Avoid loading cl-macs.el for cl-eval-when.
(let ((p (memq '&body args))) (if p (setcar p '&rest)))
(if (memq '&environment args) (error "&environment used incorrectly"))
(let ((restarg (memq '&rest args))
- (safety (if (cl--compiling-file) cl--optimize-safety 3))
+ (safety (if (macroexp-compiling-p) cl--optimize-safety 3))
(keys t)
(laterarg nil) (exactarg nil) minarg)
(or num (setq num 0))
\(fn (WHEN...) BODY...)"
(declare (indent 1) (debug (sexp body)))
- (if (and (fboundp 'cl--compiling-file) (cl--compiling-file)
+ (if (and (macroexp-compiling-p)
(not cl--not-toplevel) (not (boundp 'for-effect))) ;Horrible kludge.
(let ((comp (or (memq 'compile when) (memq :compile-toplevel when)))
(cl--not-toplevel t))
"Like `progn', but evaluates the body at load time.
The result of the body appears to the compiler as a quoted constant."
(declare (debug (form &optional sexp)))
- (if (cl--compiling-file)
+ (if (macroexp-compiling-p)
(let* ((temp (cl-gentemp "--cl-load-time--"))
(set `(setq ,temp ,form)))
(if (and (fboundp 'byte-compile-file-form-defmumble)
(defmacro cl-the (type form)
"Return FORM. If type-checking is enabled, assert that it is of TYPE."
(declare (indent 1) (debug (cl-type-spec form)))
- (if (not (or (not (cl--compiling-file))
+ (if (not (or (not (macroexp-compiling-p))
(< cl--optimize-speed 3)
(= cl--optimize-safety 3)))
form
will turn off byte-compile warnings in the function.
See Info node `(cl)Declarations' for details."
- (if (cl--compiling-file)
+ (if (macroexp-compiling-p)
(while specs
(if (listp cl--declare-stack) (push (car specs) cl--declare-stack))
(cl--do-proclaim (pop specs) nil)))
(copier (intern (format "copy-%s" name)))
(predicate (intern (format "%s-p" name)))
(print-func nil) (print-auto nil)
- (safety (if (cl--compiling-file) cl--optimize-safety 3))
+ (safety (if (macroexp-compiling-p) cl--optimize-safety 3))
(include nil)
;; There are 4 types of structs:
;; - `vector' type: means we should use a vector, which can come
"Return non-nil if SYM will be bound when we run the code.
Of course, we really can't know that for sure, so it's just a heuristic."
(or (fboundp sym)
- (and (cl--compiling-file)
+ (and (macroexp-compiling-p)
(or (cdr (assq sym byte-compile-function-environment))
(cdr (assq sym byte-compile-macro-environment))))))
"Verify that FORM is of type TYPE; signal an error if not.
STRING is an optional description of the desired type."
(declare (debug (place cl-type-spec &optional stringp)))
- (and (or (not (cl--compiling-file))
+ (and (or (not (macroexp-compiling-p))
(< cl--optimize-speed 3) (= cl--optimize-safety 3))
(macroexp-let2 macroexp-copyable-p temp form
`(progn (or (cl-typep ,temp ',type)
They are not evaluated unless the assertion fails. If STRING is
omitted, a default message listing FORM itself is used."
(declare (debug (form &rest form)))
- (and (or (not (cl--compiling-file))
+ (and (or (not (macroexp-compiling-p))
(< cl--optimize-speed 3) (= cl--optimize-safety 3))
(let ((sargs (and show-args
(delq nil (mapcar (lambda (x)
,@(when eieio-backward-compatibility
(let ((f (intern (format "%s-child-p" name))))
- `((defalias ',f ',testsym2)
+ `((defalias ',f #',testsym2)
(make-obsolete
',f ,(format "use (cl-typep ... \\='%s) instead" name)
"25.1"))))
(declare (debug (form symbolp)))
`(eieio-oref ,obj (quote ,slot)))
-(defalias 'slot-value 'eieio-oref)
-(defalias 'set-slot-value 'eieio-oset)
+(defalias 'slot-value #'eieio-oref)
+(defalias 'set-slot-value #'eieio-oset)
(make-obsolete 'set-slot-value "use (setf (slot-value ..) ..) instead" "25.1")
(defmacro oref-default (obj slot)
(cl-check-type obj eieio-object)
(eieio-class-name (eieio--object-class obj)))
(define-obsolete-function-alias
- 'object-class-name 'eieio-object-class-name "24.4")
+ 'object-class-name #'eieio-object-class-name "24.4")
(defun eieio-class-parents (class)
;; FIXME: What does "(overload of variable)" mean here?
(defmacro eieio-class-parent (class)
"Return first parent class to CLASS. (overload of variable)."
`(car (eieio-class-parents ,class)))
-(define-obsolete-function-alias 'class-parent 'eieio-class-parent "24.4")
+(define-obsolete-function-alias 'class-parent #'eieio-class-parent "24.4")
(defun same-class-p (obj class)
"Return t if OBJ is of class-type CLASS."
;; class will be checked one layer down
(child-of-class-p (eieio--object-class obj) class))
;; Backwards compatibility
-(defalias 'obj-of-class-p 'object-of-class-p)
+(defalias 'obj-of-class-p #'object-of-class-p)
(defun child-of-class-p (child class)
"Return non-nil if CHILD class is a subclass of CLASS."
(setq eieio-default-superclass (cl--find-class 'eieio-default-superclass))
(define-obsolete-function-alias 'standard-class
- 'eieio-default-superclass "26.1")
+ #'eieio-default-superclass "26.1")
(cl-defgeneric make-instance (class &rest initargs)
"Make a new instance of CLASS based on INITARGS.
This may create or delete slots, but does not affect the return value
of `eq'."
(error "EIEIO: `change-class' is unimplemented"))
-(define-obsolete-function-alias 'change-class 'eieio-change-class "26.1")
+(define-obsolete-function-alias 'change-class #'eieio-change-class "26.1")
;; Hook ourselves into help system for describing classes and methods.
;; FIXME: This is not actually needed any more since we can click on the
;; hyperlink from the constructor's docstring to see the type definition.
-(add-hook 'help-fns-describe-function-functions 'eieio-help-constructor)
+(add-hook 'help-fns-describe-function-functions #'eieio-help-constructor)
(provide 'eieio)
name will be trimmed using `string-trim' with arguments
`ert-resource-directory-trim-left-regexp' and
`ert-resource-directory-trim-right-regexp'."
- `(let* ((testfile ,(or (bound-and-true-p byte-compile-current-file)
- (and load-in-progress load-file-name)
+ `(let* ((testfile ,(or (macroexp-file-name)
buffer-file-name))
(default-directory (file-name-directory testfile)))
(file-truename
(funcall (eval (cadr form)))
(byte-compile-constant nil)))
-(defun macroexp--compiling-p ()
+(defun macroexp-compiling-p ()
"Return non-nil if we're macroexpanding for the compiler."
;; FIXME: ¡¡Major Ugly Hack!! To determine whether the output of this
;; macro-expansion will be processed by the byte-compiler, we check
(member '(declare-function . byte-compile-macroexpand-declare-function)
macroexpand-all-environment))
+(defun macroexp-file-name ()
+ "Return the name of the file from which the code comes.
+Returns nil when we do not know.
+A non-nil result is expected to be reliable when called from a macro in order
+to find the file in which the macro's call was found, and it should be
+reliable as well when used at the top-level of a file.
+Other uses risk returning non-nil value that point to the wrong file."
+ (or load-file-name (bound-and-true-p byte-compile-current-file)))
+
(defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key))
(defun macroexp--warn-and-return (msg form &optional compile-only)
(let ((when-compiled (lambda () (byte-compile-warn "%s" msg))))
(cond
((null msg) form)
- ((macroexp--compiling-p)
+ ((macroexp-compiling-p)
(if (and (consp form) (gethash form macroexp--warned))
;; Already wrapped this exp with a warning: avoid inf-looping
;; where we keep adding the same warning onto `form' because
;; the version at compile time and hardcodes it into the .elc file!
(declare (pure t))
;; Hack alert!
- (let ((file
- (or (if (boundp 'byte-compile-current-file) byte-compile-current-file)
- load-file-name
- buffer-file-name)))
+ (let ((file (or (macroexp-file-name) buffer-file-name)))
(cond
((null file) nil)
;; Packages are normally installed into directories named "<pkg>-<vers>",
the warning. If this form is included in a byte-compiled file,
the generated warning contains an indication of the file that
generated it."
- (let* ((compile-file (and (boundp 'byte-compile-current-file)
- (symbol-value 'byte-compile-current-file)))
+ (let* ((compile-file (macroexp-file-name))
(sublog (if (and
compile-file
(not load-file-name))
,(if append
`(setq ,sym (append ,sym (list ,x)))
`(push ,x ,sym))))))
- (if (not (macroexp--compiling-p))
+ (if (not (macroexp-compiling-p))
code
`(progn
(macroexp--funcall-if-compiled ',warnfun)
;; insertions are ever merged/combined, so we use such a "boundary"
;; only when the last change was an insertion and we use the position
;; of the last insertion.
- (when (numberp (caar buffer-undo-list))
+ (when (numberp (car-safe (car buffer-undo-list)))
(push (cons (caar buffer-undo-list) (caar buffer-undo-list))
buffer-undo-list))))))
obarray))
(msg (format "Package %s is deprecated" package))
(fun (lambda (msg) (message "%s" msg))))
- ;; Cribbed from cl--compiling-file.
(when (or (not (fboundp 'byte-compile-warning-enabled-p))
(byte-compile-warning-enabled-p 'obsolete package))
(cond
- ((and (boundp 'byte-compile--outbuffer)
- (bufferp (symbol-value 'byte-compile--outbuffer))
- (equal (buffer-name (symbol-value 'byte-compile--outbuffer))
- " *Compiler Output*"))
+ ((bound-and-true-p byte-compile-current-file)
;; Don't warn about obsolete files using other obsolete files.
(unless (and (stringp byte-compile-current-file)
(string-match-p "/obsolete/[^/]*\\'"