diff options
author | Yuuki Harano <masm+github@masm11.me> | 2021-07-25 23:34:55 +0900 |
---|---|---|
committer | Yuuki Harano <masm+github@masm11.me> | 2021-07-25 23:34:55 +0900 |
commit | 13a9a5e836cbe6e64aadaba40fe1f7eb83320d08 (patch) | |
tree | 242ac1f485cf6762680a904952747d63b295e198 /lisp/emacs-lisp | |
parent | b242394f24b154f8e20f5abf4b2f826629e99ea6 (diff) | |
parent | 41a55a330f518254da795719ac6e3085254d4110 (diff) | |
download | emacs-13a9a5e836cbe6e64aadaba40fe1f7eb83320d08.tar.gz emacs-13a9a5e836cbe6e64aadaba40fe1f7eb83320d08.tar.bz2 emacs-13a9a5e836cbe6e64aadaba40fe1f7eb83320d08.zip |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 19 | ||||
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 47 | ||||
-rw-r--r-- | lisp/emacs-lisp/cconv.el | 15 | ||||
-rw-r--r-- | lisp/emacs-lisp/cl-lib.el | 105 | ||||
-rw-r--r-- | lisp/emacs-lisp/copyright.el | 15 | ||||
-rw-r--r-- | lisp/emacs-lisp/eieio-core.el | 13 | ||||
-rw-r--r-- | lisp/emacs-lisp/eieio.el | 5 | ||||
-rw-r--r-- | lisp/emacs-lisp/gv.el | 100 | ||||
-rw-r--r-- | lisp/emacs-lisp/macroexp.el | 27 | ||||
-rw-r--r-- | lisp/emacs-lisp/package.el | 21 | ||||
-rw-r--r-- | lisp/emacs-lisp/shortdoc.el | 20 | ||||
-rw-r--r-- | lisp/emacs-lisp/tabulated-list.el | 24 |
12 files changed, 247 insertions, 164 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 2fff0bd4a5f..ad9f827171a 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -274,6 +274,7 @@ Earlier variables shadow later ones with the same name.") ((pred byte-code-function-p) ;; (message "Inlining byte-code for %S!" name) ;; The byte-code will be really inlined in byte-compile-unfold-bcf. + (byte-compile--check-arity-bytecode form fn) `(,fn ,@(cdr form))) ((or `(lambda . ,_) `(closure . ,_)) ;; While byte-compile-unfold-bcf can inline dynbind byte-code into @@ -300,7 +301,9 @@ Earlier variables shadow later ones with the same name.") ;; surrounded the `defsubst'. (byte-compile-warnings nil)) (byte-compile name)) - `(,(symbol-function name) ,@(cdr form)))) + (let ((bc (symbol-function name))) + (byte-compile--check-arity-bytecode form bc) + `(,bc ,@(cdr form))))) (_ ;; Give up on inlining. form)))) @@ -414,7 +417,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") form))) (t form))) (`(quote . ,v) - (if (cdr v) + (if (or (not v) (cdr v)) (byte-compile-warn "malformed quote form: `%s'" (prin1-to-string form))) ;; Map (quote nil) to nil to simplify optimizer logic. @@ -667,8 +670,7 @@ Same format as `byte-optimize--lexvars', with shared structure and contents.") (byte-compile-log " %s\t==>\t%s" old new) (setq form new) (not (eq new old)))))))) - ;; Normalise (quote nil) to nil, for a single representation of constant nil. - (and (not (equal form '(quote nil))) form)) + form) (defun byte-optimize-let-form (head form for-effect) ;; Recursively enter the optimizer for the bindings and body @@ -969,6 +971,11 @@ See Info node `(elisp) Integer Basics'." ;; Arity errors reported elsewhere. form))) +(defun byte-optimize-eq (form) + (pcase (cdr form) + ((or `(,x nil) `(nil ,x)) `(not ,x)) + (_ (byte-optimize-binary-predicate form)))) + (defun byte-optimize-member (form) ;; Replace `member' or `memql' with `memq' if the first arg is a symbol, ;; or the second arg is a list of symbols. Same with fixnums. @@ -1056,7 +1063,7 @@ See Info node `(elisp) Integer Basics'." (put 'min 'byte-optimizer #'byte-optimize-min-max) (put '= 'byte-optimizer #'byte-optimize-binary-predicate) -(put 'eq 'byte-optimizer #'byte-optimize-binary-predicate) +(put 'eq 'byte-optimizer #'byte-optimize-eq) (put 'eql 'byte-optimizer #'byte-optimize-equal) (put 'equal 'byte-optimizer #'byte-optimize-equal) (put 'string= 'byte-optimizer #'byte-optimize-binary-predicate) @@ -1072,7 +1079,7 @@ See Info node `(elisp) Integer Basics'." (defun byte-optimize-quote (form) (if (or (consp (nth 1 form)) (and (symbolp (nth 1 form)) - (not (macroexp--const-symbol-p form)))) + (not (macroexp--const-symbol-p (nth 1 form))))) form (nth 1 form))) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 6970c8a5055..f6150069e81 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1477,6 +1477,30 @@ when printing the error message." (push (list f byte-compile-last-position nargs) byte-compile-unresolved-functions))))) +(defun byte-compile-emit-callargs-warn (name actual-args min-args max-args) + (byte-compile-set-symbol-position name) + (byte-compile-warn + "%s called with %d argument%s, but %s %s" + name actual-args + (if (= 1 actual-args) "" "s") + (if (< actual-args min-args) + "requires" + "accepts only") + (byte-compile-arglist-signature-string (cons min-args max-args)))) + +(defun byte-compile--check-arity-bytecode (form bytecode) + "Check that the call in FORM matches that allowed by BYTECODE." + (when (and (byte-code-function-p bytecode) + (byte-compile-warning-enabled-p 'callargs)) + (let* ((actual-args (length (cdr form))) + (arity (func-arity bytecode)) + (min-args (car arity)) + (max-args (and (numberp (cdr arity)) (cdr arity)))) + (when (or (< actual-args min-args) + (and max-args (> actual-args max-args))) + (byte-compile-emit-callargs-warn + (car form) actual-args min-args max-args))))) + ;; Warn if the form is calling a function with the wrong number of arguments. (defun byte-compile-callargs-warn (form) (let* ((def (or (byte-compile-fdefinition (car form) nil) @@ -1491,16 +1515,9 @@ when printing the error message." (setcdr sig nil)) (if sig (when (or (< ncall (car sig)) - (and (cdr sig) (> ncall (cdr sig)))) - (byte-compile-set-symbol-position (car form)) - (byte-compile-warn - "%s called with %d argument%s, but %s %s" - (car form) ncall - (if (= 1 ncall) "" "s") - (if (< ncall (car sig)) - "requires" - "accepts only") - (byte-compile-arglist-signature-string sig)))) + (and (cdr sig) (> ncall (cdr sig)))) + (byte-compile-emit-callargs-warn + (car form) ncall (car sig) (cdr sig)))) (byte-compile-format-warn form) (byte-compile-function-warn (car form) (length (cdr form)) def))) @@ -4340,6 +4357,16 @@ Return (TAIL VAR TEST CASES), where: (push value keys) (push (cons (list value) (or body '(t))) cases)) t)))) + ;; Treat (not X) as (eq X nil). + (`((,(or 'not 'null) ,(and var (pred symbolp))) . ,body) + (and (or (eq var switch-var) (not switch-var)) + (progn + (setq switch-var var) + (setq switch-test 'eq) + (unless (memq nil keys) + (push nil keys) + (push (cons (list nil) (or body '(t))) cases)) + t))) (`((,(and fn (or 'memq 'memql 'member)) ,var ,expr) . ,body) (and (symbolp var) (or (eq var switch-var) (not switch-var)) diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index f1579cda8bd..ea0b09805ea 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -259,8 +259,7 @@ Returns a form where all lambdas don't have any free variables." (not (intern-soft var)) (eq ?_ (aref (symbol-name var) 0)) ;; As a special exception, ignore "ignore". - (eq var 'ignored) - (not (byte-compile-warning-enabled-p 'unbound var))) + (eq var 'ignored)) (let ((suggestions (help-uni-confusable-suggestions (symbol-name var)))) (format "Unused lexical %s `%S'%s" varkind var @@ -287,7 +286,7 @@ of converted forms." (let (and (pred stringp) msg) (cconv--warn-unused-msg arg "argument"))) (if (assq arg env) (push `(,arg . nil) env)) ;FIXME: Is it needed? - (push (lambda (body) (macroexp--warn-wrap msg body)) wrappers)) + (push (lambda (body) (macroexp--warn-wrap msg body 'lexical)) wrappers)) (_ (if (assq arg env) (push `(,arg . nil) env))))) (setq funcbody (mapcar (lambda (form) @@ -408,7 +407,7 @@ places where they originally did not directly appear." `(ignore ,(cconv-convert value env extend))) (msg (cconv--warn-unused-msg var "variable"))) (if (null msg) newval - (macroexp--warn-wrap msg newval)))) + (macroexp--warn-wrap msg newval 'lexical)))) ;; Normal default case. (_ @@ -507,7 +506,7 @@ places where they originally did not directly appear." (newprotform (cconv-convert protected-form env extend))) `(condition-case ,var ,(if msg - (macroexp--warn-wrap msg newprotform) + (macroexp--warn-wrap msg newprotform 'lexical) newprotform) ,@(mapcar (lambda (handler) @@ -599,14 +598,16 @@ FORM is the parent form that binds this var." (`((,(and var (guard (eq ?_ (aref (symbol-name var) 0)))) . ,_) ,_ ,_ ,_ ,_) ;; FIXME: Convert this warning to use `macroexp--warn-wrap' - ;; so as to give better position information. + ;; so as to give better position information and obey + ;; `byte-compile-warnings'. (byte-compile-warn "%s `%S' not left unused" varkind var)) ((and (let (or 'let* 'let) (car form)) `((,var) ;; (or `(,var nil) : Too many false positives: bug#47080 t nil ,_ ,_)) ;; FIXME: Convert this warning to use `macroexp--warn-wrap' - ;; so as to give better position information. + ;; so as to give better position information and obey + ;; `byte-compile-warnings'. (unless (not (intern-soft var)) (byte-compile-warn "Variable `%S' left uninitialized" var)))) (pcase vardata diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 7f7eb963423..317a4c62309 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -515,111 +515,6 @@ the process stops as soon as KEYS or VALUES run out. If ALIST is non-nil, the new pairs are prepended to it." (nconc (cl-mapcar 'cons keys values) alist)) -;;; Generalized variables. - -;; These used to be in cl-macs.el since all macros that use them (like setf) -;; were autoloaded from cl-macs.el. But now that setf, push, and pop are in -;; core Elisp, they need to either be right here or be autoloaded via -;; cl-loaddefs.el, which is more trouble than it is worth. - -;; Some more Emacs-related place types. -(gv-define-simple-setter buffer-file-name set-visited-file-name t) -(gv-define-setter buffer-modified-p (flag &optional buf) - (macroexp-let2 nil buffer `(or ,buf (current-buffer)) - `(with-current-buffer ,buffer - (set-buffer-modified-p ,flag)))) -(gv-define-simple-setter buffer-name rename-buffer t) -(gv-define-setter buffer-string (store) - `(insert (prog1 ,store (erase-buffer)))) -(gv-define-simple-setter buffer-substring cl--set-buffer-substring) -(gv-define-simple-setter current-buffer set-buffer) -(gv-define-simple-setter current-column move-to-column t) -(gv-define-simple-setter current-global-map use-global-map t) -(gv-define-setter current-input-mode (store) - `(progn (apply #'set-input-mode ,store) ,store)) -(gv-define-simple-setter current-local-map use-local-map t) -(gv-define-simple-setter current-window-configuration - set-window-configuration t) -(gv-define-simple-setter default-file-modes set-default-file-modes t) -(gv-define-simple-setter documentation-property put) -(gv-define-setter face-background (x f &optional s) - `(set-face-background ,f ,x ,s)) -(gv-define-setter face-background-pixmap (x f &optional s) - `(set-face-background-pixmap ,f ,x ,s)) -(gv-define-setter face-font (x f &optional s) `(set-face-font ,f ,x ,s)) -(gv-define-setter face-foreground (x f &optional s) - `(set-face-foreground ,f ,x ,s)) -(gv-define-setter face-underline-p (x f &optional s) - `(set-face-underline ,f ,x ,s)) -(gv-define-simple-setter file-modes set-file-modes t) -(gv-define-setter frame-height (x &optional frame) - `(set-frame-height (or ,frame (selected-frame)) ,x)) -(gv-define-simple-setter frame-parameters modify-frame-parameters t) -(gv-define-simple-setter frame-visible-p cl--set-frame-visible-p) -(gv-define-setter frame-width (x &optional frame) - `(set-frame-width (or ,frame (selected-frame)) ,x)) -(gv-define-simple-setter getenv setenv t) -(gv-define-simple-setter get-register set-register) -(gv-define-simple-setter global-key-binding global-set-key) -(gv-define-simple-setter local-key-binding local-set-key) -(gv-define-simple-setter mark set-mark t) -(gv-define-simple-setter mark-marker set-mark t) -(gv-define-simple-setter marker-position set-marker t) -(gv-define-setter mouse-position (store scr) - `(set-mouse-position ,scr (car ,store) (cadr ,store) - (cddr ,store))) -(gv-define-simple-setter point goto-char) -(gv-define-simple-setter point-marker goto-char t) -(gv-define-setter point-max (store) - `(progn (narrow-to-region (point-min) ,store) ,store)) -(gv-define-setter point-min (store) - `(progn (narrow-to-region ,store (point-max)) ,store)) -(gv-define-setter read-mouse-position (store scr) - `(set-mouse-position ,scr (car ,store) (cdr ,store))) -(gv-define-simple-setter screen-height set-screen-height t) -(gv-define-simple-setter screen-width set-screen-width t) -(gv-define-simple-setter selected-window select-window) -(gv-define-simple-setter selected-screen select-screen) -(gv-define-simple-setter selected-frame select-frame) -(gv-define-simple-setter standard-case-table set-standard-case-table) -(gv-define-simple-setter syntax-table set-syntax-table) -(gv-define-simple-setter visited-file-modtime set-visited-file-modtime t) -(gv-define-setter window-height (store) - `(progn (enlarge-window (- ,store (window-height))) ,store)) -(gv-define-setter window-width (store) - `(progn (enlarge-window (- ,store (window-width)) t) ,store)) -(gv-define-simple-setter x-get-secondary-selection x-own-secondary-selection t) - -;; More complex setf-methods. - -;; This is a hack that allows (setf (eq a 7) B) to mean either -;; (setq a 7) or (setq a nil) depending on whether B is nil or not. -;; This is useful when you have control over the PLACE but not over -;; the VALUE, as is the case in define-minor-mode's :variable. -;; It turned out that :variable needed more flexibility anyway, so -;; this doesn't seem too useful now. -(gv-define-expander eq - (lambda (do place val) - (gv-letplace (getter setter) place - (macroexp-let2 nil val val - (funcall do `(eq ,getter ,val) - (lambda (v) - `(cond - (,v ,(funcall setter val)) - ((eq ,getter ,val) ,(funcall setter `(not ,val)))))))))) - -(gv-define-expander substring - (lambda (do place from &optional to) - (gv-letplace (getter setter) place - (macroexp-let2* nil ((start from) (end to)) - (funcall do `(substring ,getter ,start ,end) - (lambda (v) - (macroexp-let2 nil v v - `(progn - ,(funcall setter `(cl--set-substring - ,getter ,start ,end ,v)) - ,v)))))))) - ;;; Miscellaneous. (provide 'cl-lib) diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el index 6ba2e7804bb..d2e4891acee 100644 --- a/lisp/emacs-lisp/copyright.el +++ b/lisp/emacs-lisp/copyright.el @@ -144,11 +144,16 @@ This function sets the match-data that `copyright-update-year' uses." (with-demoted-errors "Can't update copyright: %s" ;; (1) Need the extra \\( \\) around copyright-regexp because we ;; goto (match-end 1) below. See note (2) below. - (copyright-re-search (concat "\\(" copyright-regexp - "\\)\\([ \t]*\n\\)?.*\\(?:" - copyright-names-regexp "\\)") - (copyright-limit) - t))) + (let ((regexp (concat "\\(" copyright-regexp + "\\)\\([ \t]*\n\\)?.*\\(?:" + copyright-names-regexp "\\)"))) + (when (copyright-re-search regexp (copyright-limit) t) + ;; We may accidentally have landed in the middle of a + ;; copyright line, so re-perform the search without the + ;; search. (Otherwise we may be inserting the new year in the + ;; middle of the list of years.) + (goto-char (match-beginning 0)) + (copyright-re-search regexp nil t))))) (defun copyright-find-end () "Possibly adjust the search performed by `copyright-find-copyright'. diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index 8f1e38b613b..b11ed3333f0 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -742,7 +742,8 @@ Argument FN is the function calling this verifier." ((and (or `',name (and name (pred keywordp))) (guard (not (memq name eieio--known-slot-names)))) (macroexp-warn-and-return - (format-message "Unknown slot `%S'" name) exp 'compile-only)) + (format-message "Unknown slot `%S'" name) + exp nil 'compile-only)) (_ exp)))) (gv-setter eieio-oset)) (cl-check-type slot symbol) @@ -777,12 +778,13 @@ Fills in CLASS's SLOT with its default value." ((and (or `',name (and name (pred keywordp))) (guard (not (memq name eieio--known-slot-names)))) (macroexp-warn-and-return - (format-message "Unknown slot `%S'" name) exp 'compile-only)) + (format-message "Unknown slot `%S'" name) + exp nil 'compile-only)) ((and (or `',name (and name (pred keywordp))) (guard (not (memq name eieio--known-class-slot-names)))) (macroexp-warn-and-return (format-message "Slot `%S' is not class-allocated" name) - exp 'compile-only)) + exp nil 'compile-only)) (_ exp))))) (cl-check-type class (or eieio-object class)) (cl-check-type slot symbol) @@ -838,12 +840,13 @@ Fills in the default value in CLASS' in SLOT with VALUE." ((and (or `',name (and name (pred keywordp))) (guard (not (memq name eieio--known-slot-names)))) (macroexp-warn-and-return - (format-message "Unknown slot `%S'" name) exp 'compile-only)) + (format-message "Unknown slot `%S'" name) + exp nil 'compile-only)) ((and (or `',name (and name (pred keywordp))) (guard (not (memq name eieio--known-class-slot-names)))) (macroexp-warn-and-return (format-message "Slot `%S' is not class-allocated" name) - exp 'compile-only)) + exp nil 'compile-only)) (_ exp))))) (setq class (eieio--class-object class)) (cl-check-type class eieio--class) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index b31ea42a99b..c16d8e110ec 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -241,7 +241,8 @@ This method is obsolete." )) `(progn - ,@(mapcar (lambda (w) (macroexp-warn-and-return w `(progn ',w) 'compile-only)) + ,@(mapcar (lambda (w) + (macroexp-warn-and-return w `(progn ',w) nil 'compile-only)) warnings) ;; This test must be created right away so we can have self- ;; referencing classes. ei, a class whose slot can contain only @@ -742,7 +743,7 @@ Called from the constructor routine." (cl-defmethod initialize-instance ((this eieio-default-superclass) &optional args) - "Construct the new object THIS based on SLOTS. + "Construct the new object THIS based on ARGS. ARGS is a property list where odd numbered elements are tags, and even numbered elements are the values to store in the tagged slot. If you overload the `initialize-instance', there you will need to diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el index f08f7ac1153..d6272a52469 100644 --- a/lisp/emacs-lisp/gv.el +++ b/lisp/emacs-lisp/gv.el @@ -614,5 +614,105 @@ REF must have been previously obtained with `gv-ref'." ;; (,(nth 1 vars) (v) (funcall ',setter v))) ;; ,@body))) +;;; Generalized variables. + +;; Some Emacs-related place types. +(gv-define-simple-setter buffer-file-name set-visited-file-name t) +(gv-define-setter buffer-modified-p (flag &optional buf) + (macroexp-let2 nil buffer `(or ,buf (current-buffer)) + `(with-current-buffer ,buffer + (set-buffer-modified-p ,flag)))) +(gv-define-simple-setter buffer-name rename-buffer t) +(gv-define-setter buffer-string (store) + `(insert (prog1 ,store (erase-buffer)))) +(gv-define-simple-setter buffer-substring cl--set-buffer-substring) +(gv-define-simple-setter current-buffer set-buffer) +(gv-define-simple-setter current-column move-to-column t) +(gv-define-simple-setter current-global-map use-global-map t) +(gv-define-setter current-input-mode (store) + `(progn (apply #'set-input-mode ,store) ,store)) +(gv-define-simple-setter current-local-map use-local-map t) +(gv-define-simple-setter current-window-configuration + set-window-configuration t) +(gv-define-simple-setter default-file-modes set-default-file-modes t) +(gv-define-simple-setter documentation-property put) +(gv-define-setter face-background (x f &optional s) + `(set-face-background ,f ,x ,s)) +(gv-define-setter face-background-pixmap (x f &optional s) + `(set-face-background-pixmap ,f ,x ,s)) +(gv-define-setter face-font (x f &optional s) `(set-face-font ,f ,x ,s)) +(gv-define-setter face-foreground (x f &optional s) + `(set-face-foreground ,f ,x ,s)) +(gv-define-setter face-underline-p (x f &optional s) + `(set-face-underline ,f ,x ,s)) +(gv-define-simple-setter file-modes set-file-modes t) +(gv-define-setter frame-height (x &optional frame) + `(set-frame-height (or ,frame (selected-frame)) ,x)) +(gv-define-simple-setter frame-parameters modify-frame-parameters t) +(gv-define-simple-setter frame-visible-p cl--set-frame-visible-p) +(gv-define-setter frame-width (x &optional frame) + `(set-frame-width (or ,frame (selected-frame)) ,x)) +(gv-define-simple-setter getenv setenv t) +(gv-define-simple-setter get-register set-register) +(gv-define-simple-setter global-key-binding global-set-key) +(gv-define-simple-setter local-key-binding local-set-key) +(gv-define-simple-setter mark set-mark t) +(gv-define-simple-setter mark-marker set-mark t) +(gv-define-simple-setter marker-position set-marker t) +(gv-define-setter mouse-position (store scr) + `(set-mouse-position ,scr (car ,store) (cadr ,store) + (cddr ,store))) +(gv-define-simple-setter point goto-char) +(gv-define-simple-setter point-marker goto-char t) +(gv-define-setter point-max (store) + `(progn (narrow-to-region (point-min) ,store) ,store)) +(gv-define-setter point-min (store) + `(progn (narrow-to-region ,store (point-max)) ,store)) +(gv-define-setter read-mouse-position (store scr) + `(set-mouse-position ,scr (car ,store) (cdr ,store))) +(gv-define-simple-setter screen-height set-screen-height t) +(gv-define-simple-setter screen-width set-screen-width t) +(gv-define-simple-setter selected-window select-window) +(gv-define-simple-setter selected-screen select-screen) +(gv-define-simple-setter selected-frame select-frame) +(gv-define-simple-setter standard-case-table set-standard-case-table) +(gv-define-simple-setter syntax-table set-syntax-table) +(gv-define-simple-setter visited-file-modtime set-visited-file-modtime t) +(gv-define-setter window-height (store) + `(progn (enlarge-window (- ,store (window-height))) ,store)) +(gv-define-setter window-width (store) + `(progn (enlarge-window (- ,store (window-width)) t) ,store)) +(gv-define-simple-setter x-get-secondary-selection x-own-secondary-selection t) + +;; More complex setf-methods. + +;; This is a hack that allows (setf (eq a 7) B) to mean either +;; (setq a 7) or (setq a nil) depending on whether B is nil or not. +;; This is useful when you have control over the PLACE but not over +;; the VALUE, as is the case in define-minor-mode's :variable. +;; It turned out that :variable needed more flexibility anyway, so +;; this doesn't seem too useful now. +(gv-define-expander eq + (lambda (do place val) + (gv-letplace (getter setter) place + (macroexp-let2 nil val val + (funcall do `(eq ,getter ,val) + (lambda (v) + `(cond + (,v ,(funcall setter val)) + ((eq ,getter ,val) ,(funcall setter `(not ,val)))))))))) + +(gv-define-expander substring + (lambda (do place from &optional to) + (gv-letplace (getter setter) place + (macroexp-let2* nil ((start from) (end to)) + (funcall do `(substring ,getter ,start ,end) + (lambda (v) + (macroexp-let2 nil v v + `(progn + ,(funcall setter `(cl--set-substring + ,getter ,start ,end ,v)) + ,v)))))))) + (provide 'gv) ;;; gv.el ends here diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index f4bab9c3456..61c1ea490f0 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -135,15 +135,22 @@ Other uses risk returning non-nil value that point to the wrong file." (defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key)) -(defun macroexp--warn-wrap (msg form) - (let ((when-compiled (lambda () (byte-compile-warn "%s" msg)))) +(defun macroexp--warn-wrap (msg form category) + (let ((when-compiled (lambda () + (when (byte-compile-warning-enabled-p category) + (byte-compile-warn "%s" msg))))) `(progn (macroexp--funcall-if-compiled ',when-compiled) ,form))) (define-obsolete-function-alias 'macroexp--warn-and-return #'macroexp-warn-and-return "28.1") -(defun macroexp-warn-and-return (msg form &optional compile-only) +(defun macroexp-warn-and-return (msg form &optional category compile-only) + "Return code equivalent to FORM labeled with warning MSG. +CATEGORY is the category of the warning, like the categories that +can appear in `byte-compile-warnings'. +COMPILE-ONLY non-nil means no warning should be emitted if the code +is executed without being compiled first." (cond ((null msg) form) ((macroexp-compiling-p) @@ -153,7 +160,7 @@ Other uses risk returning non-nil value that point to the wrong file." ;; macroexpand-all gets right back to macroexpanding `form'. form (puthash form form macroexp--warned) - (macroexp--warn-wrap msg form))) + (macroexp--warn-wrap msg form category))) (t (unless compile-only (message "%sWarning: %s" @@ -205,9 +212,7 @@ Other uses risk returning non-nil value that point to the wrong file." (if (and (not (eq form new-form)) ;It was a macro call. (car-safe form) (symbolp (car form)) - (get (car form) 'byte-obsolete-info) - (or (not (fboundp 'byte-compile-warning-enabled-p)) - (byte-compile-warning-enabled-p 'obsolete (car form)))) + (get (car form) 'byte-obsolete-info)) (let* ((fun (car form)) (obsolete (get fun 'byte-obsolete-info))) (macroexp-warn-and-return @@ -215,7 +220,7 @@ Other uses risk returning non-nil value that point to the wrong file." fun obsolete (if (symbolp (symbol-function fun)) "alias" "macro")) - new-form)) + new-form 'obsolete)) new-form))) (defun macroexp--unfold-lambda (form &optional name) @@ -325,10 +330,8 @@ Assumes the caller has bound `macroexpand-all-environment'." (if (null body) (macroexp-unprogn (macroexp-warn-and-return - (and (or (not (fboundp 'byte-compile-warning-enabled-p)) - (byte-compile-warning-enabled-p t)) - (format "Empty %s body" fun)) - nil t)) + (format "Empty %s body" fun) + nil nil 'compile-only)) (macroexp--all-forms body)) (cdr form)) form)) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 6bbd4c99763..f1daa8d124a 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2195,8 +2195,24 @@ Downloads and installs required packages as needed." ((derived-mode-p 'tar-mode) (package-tar-file-info)) (t - (save-excursion - (package-buffer-info))))) + ;; Package headers should be parsed from decoded text + ;; (see Bug#48137) where possible. + (if (and (eq buffer-file-coding-system 'no-conversion) + buffer-file-name) + (let* ((package-buffer (current-buffer)) + (decoding-system + (car (find-operation-coding-system + 'insert-file-contents + (cons buffer-file-name + package-buffer))))) + (with-temp-buffer + (insert-buffer-substring package-buffer) + (decode-coding-region (point-min) (point-max) + decoding-system) + (package-buffer-info))) + + (save-excursion + (package-buffer-info)))))) (name (package-desc-name pkg-desc))) ;; Download and install the dependencies. (let* ((requires (package-desc-reqs pkg-desc)) @@ -2222,6 +2238,7 @@ directory." (setq default-directory file) (dired-mode)) (insert-file-contents-literally file) + (set-visited-file-name file) (when (string-match "\\.tar\\'" file) (tar-mode))) (package-install-from-buffer))) diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 4beba1dbed1..a74a5a4225c 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -32,14 +32,6 @@ "Short documentation." :group 'lisp) -(defface shortdoc-separator - '((((class color) (background dark)) - :height 0.1 :background "#505050" :extend t) - (((class color) (background light)) - :height 0.1 :background "#a0a0a0" :extend t) - (t :height 0.1 :inverse-video t :extend t)) - "Face used to separate sections.") - (defface shortdoc-heading '((t :inherit variable-pitch :height 1.3 :weight bold)) "Face used for a heading." @@ -281,8 +273,16 @@ There can be any number of :example/:result elements." :eval (file-relative-name "/tmp/foo" "/tmp")) (make-temp-name :eval (make-temp-name "/tmp/foo-")) + (file-name-concat + :eval (file-name-concat "/tmp/" "foo") + :eval (file-name-concat "/tmp" "foo") + :eval (file-name-concat "/tmp" "foo" "bar/" "zot") + :eval (file-name-concat "/tmp" "~")) (expand-file-name - :eval (expand-file-name "foo" "/tmp/")) + :eval (expand-file-name "foo" "/tmp/") + :eval (expand-file-name "foo" "/tmp///") + :eval (expand-file-name "foo" "/tmp/foo/.././") + :eval (expand-file-name "~" "/tmp/")) (substitute-in-file-name :eval (substitute-in-file-name "$HOME/foo")) "Directory Functions" @@ -1174,7 +1174,7 @@ If FUNCTION is non-nil, place point on the entry for FUNCTION (if any)." ;; There may be functions not yet defined in the data. ((fboundp (car data)) (when prev - (insert (propertize "\n" 'face 'shortdoc-separator))) + (insert (make-separator-line))) (setq prev t) (shortdoc--display-function data)))) (cdr (assq group shortdoc--groups)))) diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 04f3b70aaa8..f0ee78745ac 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -214,6 +214,8 @@ If ADVANCE is non-nil, move forward by one line afterwards." special-mode-map)) (define-key map "n" 'next-line) (define-key map "p" 'previous-line) + (define-key map (kbd "M-<left>") 'tabulated-list-previous-column) + (define-key map (kbd "M-<right>") 'tabulated-list-next-column) (define-key map "S" 'tabulated-list-sort) (define-key map "}" 'tabulated-list-widen-current-column) (define-key map "{" 'tabulated-list-narrow-current-column) @@ -740,6 +742,28 @@ Interactively, N is the prefix numeric argument, and defaults to (setq-local tabulated-list--current-lnum-width lnum-width) (tabulated-list-init-header))))) +(defun tabulated-list-next-column (&optional arg) + "Go to the start of the next column after point on the current line. +If ARG is provided, move that many columns." + (interactive "p") + (dotimes (_ (or arg 1)) + (let ((next (or (next-single-property-change + (point) 'tabulated-list-column-name) + (point-max)))) + (when (<= next (line-end-position)) + (goto-char next))))) + +(defun tabulated-list-previous-column (&optional arg) + "Go to the start of the column point is in on the current line. +If ARG is provided, move that many columns." + (interactive "p") + (dotimes (_ (or arg 1)) + (let ((prev (or (previous-single-property-change + (point) 'tabulated-list-column-name) + 1))) + (unless (< prev (line-beginning-position)) + (goto-char prev))))) + ;;; The mode definition: (defvar tabulated-list--original-order nil) |