aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorJoakim Verona2012-11-13 03:01:33 +0100
committerJoakim Verona2012-11-13 03:01:33 +0100
commit74fa27af7f4b50a6f5e2a378802b4c5edc11d044 (patch)
tree7030d55ecc2e06df59c08047b6f89e5b11a329dc /lisp
parent2a4942ed0e4cca22145a0d973112454c410c3dd7 (diff)
parentb95a9c0cba301ef8f1920a1d123ccd6873c14a63 (diff)
downloademacs-74fa27af7f4b50a6f5e2a378802b4c5edc11d044.tar.gz
emacs-74fa27af7f4b50a6f5e2a378802b4c5edc11d044.zip
upstream
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog231
-rw-r--r--lisp/emacs-lisp/advice.el352
-rw-r--r--lisp/emacs-lisp/bytecomp.el42
-rw-r--r--lisp/emacs-lisp/cl-extra.el7
-rw-r--r--lisp/emacs-lisp/cl-lib.el7
-rw-r--r--lisp/emacs-lisp/cl-loaddefs.el23
-rw-r--r--lisp/emacs-lisp/cl-macs.el7
-rw-r--r--lisp/emacs-lisp/cl.el54
-rw-r--r--lisp/emacs-lisp/debug.el181
-rw-r--r--lisp/emacs-lisp/elp.el332
-rw-r--r--lisp/emacs-lisp/gv.el37
-rw-r--r--lisp/emacs-lisp/nadvice.el348
-rw-r--r--lisp/env.el23
-rw-r--r--lisp/files.el49
-rw-r--r--lisp/gnus/ChangeLog5
-rw-r--r--lisp/gnus/gnus-art.el10
-rw-r--r--lisp/ido.el6
-rw-r--r--lisp/mail/emacsbug.el88
-rw-r--r--lisp/minibuf-eldef.el20
-rw-r--r--lisp/minibuffer.el8
-rw-r--r--lisp/net/tramp.el32
-rw-r--r--lisp/progmodes/js.el35
-rw-r--r--lisp/progmodes/perl-mode.el121
-rw-r--r--lisp/progmodes/ruby-mode.el2
-rw-r--r--lisp/progmodes/sql.el47
-rw-r--r--lisp/server.el9
-rw-r--r--lisp/ses.el92
-rw-r--r--lisp/subr.el23
-rw-r--r--lisp/term.el18
-rw-r--r--lisp/vc/diff-mode.el96
-rw-r--r--lisp/woman.el4
31 files changed, 1426 insertions, 883 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 7c51b139ec3..f53b58b0129 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,228 @@
12012-11-12 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/nadvice.el: New package.
4 * subr.el (special-form-p): New function.
5 * emacs-lisp/elp.el: Use lexical-binding and advice-add.
6 (elp-all-instrumented-list): Remove var.
7 (elp-not-profilable): Remove elp-wrapper.
8 (elp-profilable-p): Use autoloadp and special-form-p.
9 (elp--advice-name): New const.
10 (elp-instrument-function): Use advice-add.
11 (elp--instrumented-p): New predicate.
12 (elp-restore-function): Use advice-remove.
13 (elp-restore-all, elp-reset-all): Use mapatoms.
14 (elp-set-master): Use elp--instrumented-p.
15 (elp--make-wrapper): Rename from elp-wrapper, return a function
16 suitable for advice-add. Use cl-inf.
17 (elp-results): Use mapatoms+elp--instrumented-p.
18 * emacs-lisp/debug.el: Use lexical-binding and advice-add.
19 (debug-function-list): Remove var.
20 (debug): Rename arg, and then let-bind it explicitly inside.
21 (debugger-setup-buffer): Rename arg.
22 (debugger-setup-buffer): Adjust counts to new debug-on-entry setup.
23 (debugger-frame-number): Adjust to new debug-on-entry setup.
24 (debug--implement-debug-on-entry): Rename from
25 implement-debug-on-entry, add argument.
26 (debugger-special-form-p): Remove, use special-form-p instead.
27 (debug-on-entry): Use advice-add.
28 (debug--function-list): New function.
29 (cancel-debug-on-entry): Use it, along with advice-remove.
30 (debug-arglist, debug-convert-byte-code, debug-on-entry-1): Remove.
31 (debugger-list-functions): Use debug--function-list instead of
32 debug-function-list.
33 * emacs-lisp/advice.el (ad-save-real-definition): Remove, unused.
34 (ad-special-form-p): Remove, use special-form-p instead.
35 (ad-set-advice-info): Use add-function and remove-function.
36 (ad--defalias-fset): Adjust accordingly.
37
382012-11-10 Glenn Morris <rgm@gnu.org>
39
40 * mail/emacsbug.el (report-emacs-bug-tracker-url)
41 (report-emacs-bug-bug-alist, report-emacs-bug-choice-widget)
42 (report-emacs-bug-create-existing-bugs-buffer)
43 (report-emacs-bug-parse-query-results)
44 (report-emacs-bug-query-existing-bugs): Remove. (Bug#7449)
45
46 * term.el (term-default-fg-color, term-default-bg-color):
47 Make obsolete, rather than just saying "deprecated" in the doc.
48
49 * term.el (term): Rename from `term-face'.
50 (term-current-face, ansi-term-color-vector)
51 (term-default-fg-color, term-default-bg-color, term-ansi-reset):
52 Update all users.
53
542012-11-10 Jan Djärv <jan.h.d@swipnet.se>
55
56 * server.el (server-create-window-system-frame): Handle Nextstep
57 specially (Bug#12780).
58
592012-11-10 Glenn Morris <rgm@gnu.org>
60
61 * mail/emacsbug.el (report-emacs-bug-query-existing-bugs):
62 Unautoload, and make obsolete. (Bug#7449)
63
642012-11-10 Chong Yidong <cyd@gnu.org>
65
66 * vc/diff-mode.el (diff-delete-trailing-whitespace): Rewrite, and
67 rename from diff-remove-trailing-whitespace (Bug#12831).
68
692012-11-10 Stefan Monnier <monnier@iro.umontreal.ca>
70
71 * emacs-lisp/advice.el: Require `cl-lib' at run-time to fix
72 miscompilation of trace.el.
73
742012-11-10 Glenn Morris <rgm@gnu.org>
75
76 * vc/diff-mode.el (diff-remove-trailing-whitespace): Doc fix.
77
782012-11-10 Stefan Monnier <monnier@iro.umontreal.ca>
79
80 * emacs-lisp/gv.el (gv-define-simple-setter): Fix last change
81 (bug#12812).
82
832012-11-10 Chong Yidong <cyd@gnu.org>
84
85 * minibuf-eldef.el (minibuffer-eldef-shorten-default): Convert to
86 a defcustom with an appropriate :set function.
87 (minibuffer-default--in-prompt-regexps): New function.
88
892012-11-10 Glenn Morris <rgm@gnu.org>
90
91 * emacs-lisp/cl.el (define-setf-expander, defsetf)
92 (define-modify-macro): Doc fixes.
93
94 * emacs-lisp/gv.el (gv-letplace): Fix doc typo.
95 (gv-define-simple-setter): Update doc of `fix-return'.
96
972012-11-10 Stefan Monnier <monnier@iro.umontreal.ca>
98
99 * emacs-lisp/gv.el (gv-define-simple-setter): Don't evaluate `val'
100 twice when `fix-return' is set (bug#12813).
101
102 * emacs-lisp/cl.el (defsetf): Pass the third arg to
103 gv-define-simple-setter (bug#12812).
104
105 * woman.el (woman-decode-region): Disable adaptive-fill when rendering
106 (bug#12756).
107
1082012-11-10 Glenn Morris <rgm@gnu.org>
109
110 * emacs-lisp/gv.el (gv-define-setter): Fix doc typo.
111
112 * emacs-lisp/cl-extra.el (cl-prettyexpand):
113 * emacs-lisp/cl-lib.el (cl-proclaim, cl-declaim):
114 * emacs-lisp/cl-macs.el (cl-destructuring-bind, cl-locally)
115 (cl-the, cl-compiler-macroexpand): Add basic doc strings.
116
117 * emacs-lisp/cl-extra.el (cl-maplist, cl-mapcan): Doc fix.
118
1192012-11-10 Leo Liu <sdl.web@gmail.com>
120
121 * ido.el (ido-set-matches-1): Improve flex matching performance by
122 removing backtracking in the regexp (suggested by Stefan). (Bug#12796)
123
1242012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
125
126 * emacs-lisp/advice.el (ad-set-advice-info): Set defalias-fset-function.
127 (ad--defalias-fset): New function.
128 (ad-safe-fset): Remove.
129 (ad-make-freeze-definition): Use cl-letf*.
130
1312012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
132
133 * subr.el (dolist): Don't bind VAR in RESULT.
134
135 * emacs-lisp/advice.el: Miscellaneous cleanup. Use lexical-binding.
136 (fset, documentation): Don't save real def since we don't advise.
137 (ad-do-advised-functions): Remove problematic `result-form'.
138 (ad-safe-fset): `ad-real-fset' => `fset'.
139 (ad-read-advised-function): Don't assume that ad-do-advised-functions
140 uses CL's dolist internally.
141 (ad-arglist): Remove unused arg `name'.
142 (ad-docstring, ad-make-advised-docstring):
143 `ad-real-documentation' => `documentation'.
144 (warning-suppress-types): Declare.
145 (ad-set-arguments): Simple CSE.
146 (ad-recover-normality): Sanity check.
147
148 * emacs-lisp/bytecomp.el (byte-compile-out-toplevel): Don't turn
149 (funcall '(lambda ..) ..) into ((lambda ..) ..).
150
1512012-11-09 Vincent Belaïche <vincentb1@users.sourceforge.net>
152
153 * ses.el: symbol to coordinate mapping is made by symbol property
154 `ses-cell'. This means that the same mapping is done for all SES
155 sheets. That is good enough for cells with standard A1 names, but
156 not for named cell. So a hash map is added for the latter.
157 (defconst ses-localvars): Add local variable ses--named-cell-hashmap
158 (ses-sym-rowcol): Use hashmap for named cell.
159 (ses-is-cell-sym-p): New defun.
160 (ses-decode-cell-symbol): New defun.
161 (ses-create-cell-variable): Add cell to hashmap when name is not
162 A1-like.
163 (ses-rename-cell): Check that cell new name is not already in
164 spreadsheet with the use of ses-is-cell-sym-p
165 (ses-rename-cell): Use hash map for named cells, but accept also
166 renaming back to A1-like.
167
1682012-11-09 Stefan Monnier <monnier@iro.umontreal.ca>
169
170 * emacs-lisp/advice.el: Use new dynamic docstrings.
171 (ad-make-advised-definition-docstring, ad-advised-definition-p):
172 Use dynamic-docstring-function instead of ad-advice-info.
173 (ad--make-advised-docstring): New function extracted from
174 ad-make-advised-docstring.
175 (ad-make-advised-docstring): Use it.
176 * progmodes/sql.el (sql--make-help-docstring): New function, extracted
177 from sql-help.
178 (sql-help): Use it with dynamic-docstring-function.
179
180 * env.el (env--substitute-vars-regexp): Don't use rx (for bootstrap).
181
1822012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
183
184 * files.el (hack-one-local-variable--obsolete): New function.
185 (hack-one-local-variable): Use it for obsolete settings.
186
187 * subr.el (locate-user-emacs-file): If both old and new name exist, use
188 the new name.
189
190 * progmodes/js.el (js--filling-paragraph): New var.
191 (c-forward-sws, c-backward-sws, c-beginning-of-macro): Advise.
192 (js-c-fill-paragraph): Prefer advice to cl-letf so the rebinding is
193 less sneaky.
194
1952012-11-08 Julien Danjou <julien@danjou.info>
196
197 * progmodes/ruby-mode.el (auto-mode-alist): Add Rakefile in
198 `auto-mode-alist' (Bug#12835).
199
2002012-11-08 Stefan Monnier <monnier@iro.umontreal.ca>
201
202 * progmodes/perl-mode.el (perl-prettify-symbols): New defcustom.
203 (perl--prettify-symbols-alist): New const.
204 (perl--font-lock-compose-symbol, perl--font-lock-symbols-keywords):
205 New functions.
206 (perl-font-lock-keywords-2): Use them.
207 (perl-electric-noindent-p): New function.
208 (perl-mode): Use it to set up electric-indent-mode.
209 (perl-electric-terminator, perl-indent-command): Mark obsolete.
210 (perl-mode-map): Remove bindings for them.
211 (perl-imenu-generic-expression, perl-outline-level):
212 Match functions&packages in column>0.
213
214 * env.el (env--substitute-vars-regexp): New const.
215 (substitute-env-vars): Use it. Add `only-defined' arg.
216 * net/tramp.el (tramp-replace-environment-variables): Use it.
217
218 * emacs-lisp/bytecomp.el (byte-compile-initial-macro-environment):
219 Byte-compile *before* eval in eval-and-compile.
220 (byte-compile-log-warning): Remove redundant inhibit-read-only.
221 (byte-compile-file-form-autoload): Don't hide actual definition.
222 (byte-compile-maybe-guarded): Accept `functionp' as well.
223
224 * emacs-lisp/gv.el (gv-ref, gv-deref): New function and macro.
225
12012-11-07 Michael Albinus <michael.albinus@gmx.de> 2262012-11-07 Michael Albinus <michael.albinus@gmx.de>
2 227
3 * notifications.el (notifications-get-server-information-method): 228 * notifications.el (notifications-get-server-information-method):
@@ -45,8 +270,8 @@
45 270
462012-11-05 Agustín Martín Domingo <agustin.martin@hispalinux.es> 2712012-11-05 Agustín Martín Domingo <agustin.martin@hispalinux.es>
47 272
48 * textmodes/ispell.el (ispell-program-name): Update 273 * textmodes/ispell.el (ispell-program-name):
49 spellchecker parameters when customized. 274 Update spellchecker parameters when customized.
50 275
512012-11-04 Glenn Morris <rgm@gnu.org> 2762012-11-04 Glenn Morris <rgm@gnu.org>
52 277
@@ -440,7 +665,7 @@
4402012-10-19 Stefan Monnier <monnier@iro.umontreal.ca> 6652012-10-19 Stefan Monnier <monnier@iro.umontreal.ca>
441 666
442 * minibuffer.el (minibuffer-force-complete): Make the next completion use 667 * minibuffer.el (minibuffer-force-complete): Make the next completion use
443 the same completion-field (bug@12221). 668 the same completion-field (bug#12221).
444 669
4452012-10-19 Martin Rudalics <rudalics@gmx.at> 6702012-10-19 Martin Rudalics <rudalics@gmx.at>
446 671
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index bd85238e23e..16c12aad29b 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -1,4 +1,4 @@
1;;; advice.el --- An overloading mechanism for Emacs Lisp functions 1;;; advice.el --- An overloading mechanism for Emacs Lisp functions -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 1993-1994, 2000-2012 Free Software Foundation, Inc. 3;; Copyright (C) 1993-1994, 2000-2012 Free Software Foundation, Inc.
4 4
@@ -1709,7 +1709,8 @@
1709;; During a normal load this is a noop: 1709;; During a normal load this is a noop:
1710(require 'advice-preload "advice.el") 1710(require 'advice-preload "advice.el")
1711(require 'macroexp) 1711(require 'macroexp)
1712(eval-when-compile (require 'cl-lib)) 1712;; At run-time also, since ad-do-advised-functions returns code that uses it.
1713(require 'cl-lib)
1713 1714
1714;; @@ Variable definitions: 1715;; @@ Variable definitions:
1715;; ======================== 1716;; ========================
@@ -1775,36 +1776,6 @@ generates a copy of TREE."
1775 (funcall fUnCtIoN tReE)) 1776 (funcall fUnCtIoN tReE))
1776 (t tReE))) 1777 (t tReE)))
1777 1778
1778;; @@ Save real definitions of subrs used by Advice:
1779;; =================================================
1780;; Advice depends on the real, unmodified functionality of various subrs,
1781;; we save them here so advised versions will not interfere (eventually,
1782;; we will save all subrs used in code generated by Advice):
1783
1784(defmacro ad-save-real-definition (function)
1785 (let ((saved-function (intern (format "ad-real-%s" function))))
1786 ;; Make sure the compiler is loaded during macro expansion:
1787 (require 'byte-compile "bytecomp")
1788 `(if (not (fboundp ',saved-function))
1789 (progn (fset ',saved-function (symbol-function ',function))
1790 ;; Copy byte-compiler properties:
1791 ,@(if (get function 'byte-compile)
1792 `((put ',saved-function 'byte-compile
1793 ',(get function 'byte-compile))))
1794 ,@(if (get function 'byte-opcode)
1795 `((put ',saved-function 'byte-opcode
1796 ',(get function 'byte-opcode))))))))
1797
1798(defun ad-save-real-definitions ()
1799 ;; Macro expansion will hardcode the values of the various byte-compiler
1800 ;; properties into the compiled version of this function such that the
1801 ;; proper values will be available at runtime without loading the compiler:
1802 (ad-save-real-definition fset)
1803 (ad-save-real-definition documentation))
1804
1805(ad-save-real-definitions)
1806
1807
1808;; @@ Advice info access fns: 1779;; @@ Advice info access fns:
1809;; ========================== 1780;; ==========================
1810 1781
@@ -1839,15 +1810,13 @@ generates a copy of TREE."
1839 ad-advised-functions))) 1810 ad-advised-functions)))
1840 1811
1841(defmacro ad-do-advised-functions (varform &rest body) 1812(defmacro ad-do-advised-functions (varform &rest body)
1842 "`dolist'-style iterator that maps over `ad-advised-functions'. 1813 "`dolist'-style iterator that maps over advised functions.
1843\(ad-do-advised-functions (VAR [RESULT-FORM]) 1814\(ad-do-advised-functions (VAR)
1844 BODY-FORM...) 1815 BODY-FORM...)
1845On each iteration VAR will be bound to the name of an advised function 1816On each iteration VAR will be bound to the name of an advised function
1846\(a symbol)." 1817\(a symbol)."
1847 (declare (indent 1)) 1818 (declare (indent 1))
1848 `(cl-dolist (,(car varform) 1819 `(cl-dolist (,(car varform) ad-advised-functions)
1849 ad-advised-functions
1850 ,(car (cdr varform)))
1851 (setq ,(car varform) (intern (car ,(car varform)))) 1820 (setq ,(car varform) (intern (car ,(car varform))))
1852 ,@body)) 1821 ,@body))
1853 1822
@@ -1857,8 +1826,15 @@ On each iteration VAR will be bound to the name of an advised function
1857(defmacro ad-get-advice-info-macro (function) 1826(defmacro ad-get-advice-info-macro (function)
1858 `(get ,function 'ad-advice-info)) 1827 `(get ,function 'ad-advice-info))
1859 1828
1860(defmacro ad-set-advice-info (function advice-info) 1829(defsubst ad-set-advice-info (function advice-info)
1861 `(put ,function 'ad-advice-info ,advice-info)) 1830 (cond
1831 (advice-info
1832 (add-function :around (get function 'defalias-fset-function)
1833 #'ad--defalias-fset))
1834 ((get function 'defalias-fset-function)
1835 (remove-function (get function 'defalias-fset-function)
1836 #'ad--defalias-fset)))
1837 (put function 'ad-advice-info advice-info))
1862 1838
1863(defmacro ad-copy-advice-info (function) 1839(defmacro ad-copy-advice-info (function)
1864 `(copy-tree (get ,function 'ad-advice-info))) 1840 `(copy-tree (get ,function 'ad-advice-info)))
@@ -1866,7 +1842,7 @@ On each iteration VAR will be bound to the name of an advised function
1866(defmacro ad-is-advised (function) 1842(defmacro ad-is-advised (function)
1867 "Return non-nil if FUNCTION has any advice info associated with it. 1843 "Return non-nil if FUNCTION has any advice info associated with it.
1868This does not mean that the advice is also active." 1844This does not mean that the advice is also active."
1869 (list 'ad-get-advice-info-macro function)) 1845 `(ad-get-advice-info-macro ,function))
1870 1846
1871(defun ad-initialize-advice-info (function) 1847(defun ad-initialize-advice-info (function)
1872 "Initialize the advice info for FUNCTION. 1848 "Initialize the advice info for FUNCTION.
@@ -1949,7 +1925,7 @@ Redefining advices affect the construction of an advised definition."
1949(defun ad-has-any-advice (function) 1925(defun ad-has-any-advice (function)
1950 "True if the advice info of FUNCTION defines at least one advice." 1926 "True if the advice info of FUNCTION defines at least one advice."
1951 (and (ad-is-advised function) 1927 (and (ad-is-advised function)
1952 (cl-dolist (class ad-advice-classes nil) 1928 (cl-dolist (class ad-advice-classes)
1953 (if (ad-get-advice-info-field function class) 1929 (if (ad-get-advice-info-field function class)
1954 (cl-return t))))) 1930 (cl-return t)))))
1955 1931
@@ -1965,18 +1941,10 @@ Redefining advices affect the construction of an advised definition."
1965;; @@ Dealing with automatic advice activation via `fset/defalias': 1941;; @@ Dealing with automatic advice activation via `fset/defalias':
1966;; ================================================================ 1942;; ================================================================
1967 1943
1968;; Since Emacs 19.26 the built-in versions of `fset' and `defalias' 1944;; Automatic activation happens when a function gets defined via `defalias',
1969;; take care of automatic advice activation, hence, we don't have to 1945;; which calls the `defalias-fset-function' (which we set to
1970;; hack it anymore by advising `fset/defun/defmacro/byte-code/etc'. 1946;; `ad--defalias-fset') instead of `fset', if non-nil.
1971 1947
1972;; The functionality of the new `fset' is as follows:
1973;;
1974;; fset(sym,newdef)
1975;; assign NEWDEF to SYM
1976;; if (get SYM 'ad-advice-info)
1977;; ad-activate-internal(SYM, nil)
1978;; return (symbol-function SYM)
1979;;
1980;; Whether advised definitions created by automatic activations will be 1948;; Whether advised definitions created by automatic activations will be
1981;; compiled depends on the value of `ad-default-compilation-action'. 1949;; compiled depends on the value of `ad-default-compilation-action'.
1982 1950
@@ -1988,13 +1956,17 @@ Redefining advices affect the construction of an advised definition."
1988;; to `ad-activate' by using `ad-with-auto-activation-disabled' where 1956;; to `ad-activate' by using `ad-with-auto-activation-disabled' where
1989;; appropriate, especially in a safe version of `fset'. 1957;; appropriate, especially in a safe version of `fset'.
1990 1958
1959(defun ad--defalias-fset (fsetfun function definition)
1960 (funcall (or fsetfun #'fset) function definition)
1961 (ad-activate-internal function nil))
1962
1991;; For now define `ad-activate-internal' to the dummy definition: 1963;; For now define `ad-activate-internal' to the dummy definition:
1992(defun ad-activate-internal (function &optional compile) 1964(defun ad-activate-internal (_function &optional _compile)
1993 "Automatic advice activation is disabled. `ad-start-advice' enables it." 1965 "Automatic advice activation is disabled. `ad-start-advice' enables it."
1994 nil) 1966 nil)
1995 1967
1996;; This is just a copy of the above: 1968;; This is just a copy of the above:
1997(defun ad-activate-internal-off (function &optional compile) 1969(defun ad-activate-internal-off (_function &optional _compile)
1998 "Automatic advice activation is disabled. `ad-start-advice' enables it." 1970 "Automatic advice activation is disabled. `ad-start-advice' enables it."
1999 nil) 1971 nil)
2000 1972
@@ -2005,12 +1977,6 @@ Redefining advices affect the construction of an advised definition."
2005 `(let ((ad-activate-on-top-level nil)) 1977 `(let ((ad-activate-on-top-level nil))
2006 ,@body)) 1978 ,@body))
2007 1979
2008(defun ad-safe-fset (symbol definition)
2009 "A safe `fset' which will never call `ad-activate-internal' recursively."
2010 (ad-with-auto-activation-disabled
2011 (ad-real-fset symbol definition)))
2012
2013
2014;; @@ Access functions for original definitions: 1980;; @@ Access functions for original definitions:
2015;; ============================================ 1981;; ============================================
2016;; The advice-info of an advised function contains its `origname' which is 1982;; The advice-info of an advised function contains its `origname' which is
@@ -2030,8 +1996,7 @@ Redefining advices affect the construction of an advised definition."
2030 (symbol-function origname)))) 1996 (symbol-function origname))))
2031 1997
2032(defmacro ad-set-orig-definition (function definition) 1998(defmacro ad-set-orig-definition (function definition)
2033 `(ad-safe-fset 1999 `(fset (ad-get-advice-info-field ,function 'origname) ,definition))
2034 (ad-get-advice-info-field ,function 'origname) ,definition))
2035 2000
2036(defmacro ad-clear-orig-definition (function) 2001(defmacro ad-clear-orig-definition (function)
2037 `(fmakunbound (ad-get-advice-info-field ,function 'origname))) 2002 `(fmakunbound (ad-get-advice-info-field ,function 'origname)))
@@ -2052,7 +2017,7 @@ function at point for which PREDICATE returns non-nil)."
2052 (error "ad-read-advised-function: There are no advised functions")) 2017 (error "ad-read-advised-function: There are no advised functions"))
2053 (setq default 2018 (setq default
2054 (or default 2019 (or default
2055 ;; Prefer func name at point, if it's in ad-advised-functions etc. 2020 ;; Prefer func name at point, if it's an advised function etc.
2056 (let ((function (progn 2021 (let ((function (progn
2057 (require 'help) 2022 (require 'help)
2058 (function-called-at-point)))) 2023 (function-called-at-point))))
@@ -2061,24 +2026,20 @@ function at point for which PREDICATE returns non-nil)."
2061 (or (null predicate) 2026 (or (null predicate)
2062 (funcall predicate function)) 2027 (funcall predicate function))
2063 function)) 2028 function))
2064 (ad-do-advised-functions (function) 2029 (cl-block nil
2065 (if (or (null predicate) 2030 (ad-do-advised-functions (function)
2066 (funcall predicate function)) 2031 (if (or (null predicate)
2067 (cl-return function))) 2032 (funcall predicate function))
2033 (cl-return function))))
2068 (error "ad-read-advised-function: %s" 2034 (error "ad-read-advised-function: %s"
2069 "There are no qualifying advised functions"))) 2035 "There are no qualifying advised functions")))
2070 (let* ((ad-pReDiCaTe predicate) 2036 (let* ((function
2071 (function
2072 (completing-read 2037 (completing-read
2073 (format "%s (default %s): " (or prompt "Function") default) 2038 (format "%s (default %s): " (or prompt "Function") default)
2074 ad-advised-functions 2039 ad-advised-functions
2075 (if predicate 2040 (if predicate
2076 (function 2041 (lambda (function)
2077 (lambda (function) 2042 (funcall predicate (intern (car function)))))
2078 ;; Oops, no closures - the joys of dynamic scoping:
2079 ;; `predicate' clashed with the `predicate' argument
2080 ;; of `completing-read'.....
2081 (funcall ad-pReDiCaTe (intern (car function))))))
2082 t))) 2043 t)))
2083 (if (equal function "") 2044 (if (equal function "")
2084 (if (ad-is-advised default) 2045 (if (ad-is-advised default)
@@ -2331,12 +2292,6 @@ See Info node `(elisp)Computed Advice' for detailed documentation."
2331 "Take a macro function DEFINITION and make a lambda out of it." 2292 "Take a macro function DEFINITION and make a lambda out of it."
2332 `(cdr ,definition)) 2293 `(cdr ,definition))
2333 2294
2334(defun ad-special-form-p (definition)
2335 "Non-nil if and only if DEFINITION is a special form."
2336 (if (and (symbolp definition) (fboundp definition))
2337 (setq definition (indirect-function definition)))
2338 (and (subrp definition) (eq (cdr (subr-arity definition)) 'unevalled)))
2339
2340(defmacro ad-subr-p (definition) 2295(defmacro ad-subr-p (definition)
2341 ;;"non-nil if DEFINITION is a subr." 2296 ;;"non-nil if DEFINITION is a subr."
2342 (list 'subrp definition)) 2297 (list 'subrp definition))
@@ -2376,10 +2331,8 @@ See Info node `(elisp)Computed Advice' for detailed documentation."
2376 (cdr definition)) 2331 (cdr definition))
2377 (t nil))) 2332 (t nil)))
2378 2333
2379(defun ad-arglist (definition &optional name) 2334(defun ad-arglist (definition)
2380 "Return the argument list of DEFINITION. 2335 "Return the argument list of DEFINITION."
2381If DEFINITION could be from a subr then its NAME should be
2382supplied to make subr arglist lookup more efficient."
2383 (require 'help-fns) 2336 (require 'help-fns)
2384 (help-function-arglist 2337 (help-function-arglist
2385 (if (or (ad-macro-p definition) (ad-advice-p definition)) 2338 (if (or (ad-macro-p definition) (ad-advice-p definition))
@@ -2391,7 +2344,7 @@ supplied to make subr arglist lookup more efficient."
2391 "Return the unexpanded docstring of DEFINITION." 2344 "Return the unexpanded docstring of DEFINITION."
2392 (let ((docstring 2345 (let ((docstring
2393 (if (ad-compiled-p definition) 2346 (if (ad-compiled-p definition)
2394 (ad-real-documentation definition t) 2347 (documentation definition t)
2395 (car (cdr (cdr (ad-lambda-expression definition))))))) 2348 (car (cdr (cdr (ad-lambda-expression definition)))))))
2396 (if (or (stringp docstring) 2349 (if (or (stringp docstring)
2397 (natnump docstring)) 2350 (natnump docstring))
@@ -2414,13 +2367,15 @@ Like `interactive-form', but also works on pieces of advice."
2414 (if (ad-interactive-form definition) 1 0)) 2367 (if (ad-interactive-form definition) 1 0))
2415 (cdr (cdr (ad-lambda-expression definition))))))) 2368 (cdr (cdr (ad-lambda-expression definition)))))))
2416 2369
2417(defun ad-make-advised-definition-docstring (function) 2370(defun ad-make-advised-definition-docstring (_function)
2418 "Make an identifying docstring for the advised definition of FUNCTION. 2371 "Make an identifying docstring for the advised definition of FUNCTION.
2419Put function name into the documentation string so we can infer 2372Put function name into the documentation string so we can infer
2420the name of the advised function from the docstring. This is needed 2373the name of the advised function from the docstring. This is needed
2421to generate a proper advised docstring even if we are just given a 2374to generate a proper advised docstring even if we are just given a
2422definition (see the code for `documentation')." 2375definition (see the code for `documentation')."
2423 (propertize "Advice doc string" 'ad-advice-info function)) 2376 (eval-when-compile
2377 (propertize "Advice doc string" 'dynamic-docstring-function
2378 #'ad--make-advised-docstring)))
2424 2379
2425(defun ad-advised-definition-p (definition) 2380(defun ad-advised-definition-p (definition)
2426 "Return non-nil if DEFINITION was generated from advice information." 2381 "Return non-nil if DEFINITION was generated from advice information."
@@ -2429,14 +2384,14 @@ definition (see the code for `documentation')."
2429 (ad-compiled-p definition)) 2384 (ad-compiled-p definition))
2430 (let ((docstring (ad-docstring definition))) 2385 (let ((docstring (ad-docstring definition)))
2431 (and (stringp docstring) 2386 (and (stringp docstring)
2432 (get-text-property 0 'ad-advice-info docstring))))) 2387 (get-text-property 0 'dynamic-docstring-function docstring)))))
2433 2388
2434(defun ad-definition-type (definition) 2389(defun ad-definition-type (definition)
2435 "Return symbol that describes the type of DEFINITION." 2390 "Return symbol that describes the type of DEFINITION."
2436 (cond 2391 (cond
2437 ((ad-macro-p definition) 'macro) 2392 ((ad-macro-p definition) 'macro)
2438 ((ad-subr-p definition) 2393 ((ad-subr-p definition)
2439 (if (ad-special-form-p definition) 2394 (if (special-form-p definition)
2440 'special-form 2395 'special-form
2441 'subr)) 2396 'subr))
2442 ((or (ad-lambda-p definition) 2397 ((or (ad-lambda-p definition)
@@ -2473,6 +2428,7 @@ For that it has to be fbound with a non-autoload definition."
2473 (ad-macro-p (symbol-function function))) 2428 (ad-macro-p (symbol-function function)))
2474 (not (ad-compiled-p (symbol-function function))))) 2429 (not (ad-compiled-p (symbol-function function)))))
2475 2430
2431(defvar warning-suppress-types) ;From warnings.el.
2476(defun ad-compile-function (function) 2432(defun ad-compile-function (function)
2477 "Byte-compiles FUNCTION (or macro) if it is not yet compiled." 2433 "Byte-compiles FUNCTION (or macro) if it is not yet compiled."
2478 (interactive "aByte-compile function: ") 2434 (interactive "aByte-compile function: ")
@@ -2603,24 +2559,20 @@ The assignment starts at position INDEX."
2603 (let ((values-index 0) 2559 (let ((values-index 0)
2604 argument-access set-forms) 2560 argument-access set-forms)
2605 (while (setq argument-access (ad-access-argument arglist index)) 2561 (while (setq argument-access (ad-access-argument arglist index))
2606 (if (symbolp argument-access) 2562 (push (if (symbolp argument-access)
2607 (setq set-forms 2563 (ad-set-argument
2608 (cons (ad-set-argument 2564 arglist index
2609 arglist index 2565 (ad-element-access values-index 'ad-vAlUeS))
2610 (ad-element-access values-index 'ad-vAlUeS)) 2566 (setq arglist nil) ;; Terminate loop.
2611 set-forms)) 2567 (if (= (car argument-access) 0)
2612 (setq set-forms 2568 `(setq
2613 (cons (if (= (car argument-access) 0) 2569 ,(car (cdr argument-access))
2614 (list 'setq 2570 ,(ad-list-access values-index 'ad-vAlUeS))
2615 (car (cdr argument-access)) 2571 `(setcdr
2616 (ad-list-access values-index 'ad-vAlUeS)) 2572 ,(ad-list-access (1- (car argument-access))
2617 (list 'setcdr 2573 (car (cdr argument-access)))
2618 (ad-list-access (1- (car argument-access)) 2574 ,(ad-list-access values-index 'ad-vAlUeS))))
2619 (car (cdr argument-access))) 2575 set-forms)
2620 (ad-list-access values-index 'ad-vAlUeS)))
2621 set-forms))
2622 ;; terminate loop
2623 (setq arglist nil))
2624 (setq index (1+ index)) 2576 (setq index (1+ index))
2625 (setq values-index (1+ values-index))) 2577 (setq values-index (1+ values-index)))
2626 (if (null set-forms) 2578 (if (null set-forms)
@@ -2629,8 +2581,8 @@ The assignment starts at position INDEX."
2629 (if (= (length set-forms) 1) 2581 (if (= (length set-forms) 1)
2630 ;; For exactly one set-form we can use values-form directly,... 2582 ;; For exactly one set-form we can use values-form directly,...
2631 (ad-substitute-tree 2583 (ad-substitute-tree
2632 (function (lambda (form) (eq form 'ad-vAlUeS))) 2584 (lambda (form) (eq form 'ad-vAlUeS))
2633 (function (lambda (form) values-form)) 2585 (lambda (_form) values-form)
2634 (car set-forms)) 2586 (car set-forms))
2635 ;; ...if we have more we have to bind it to a variable: 2587 ;; ...if we have more we have to bind it to a variable:
2636 `(let ((ad-vAlUeS ,values-form)) 2588 `(let ((ad-vAlUeS ,values-form))
@@ -2700,11 +2652,10 @@ Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2700 (cond (need-apply 2652 (cond (need-apply
2701 ;; `apply' can take care of that directly: 2653 ;; `apply' can take care of that directly:
2702 (append source-reqopt-args (list source-rest-arg))) 2654 (append source-reqopt-args (list source-rest-arg)))
2703 (t (mapcar (function 2655 (t (mapcar (lambda (_arg)
2704 (lambda (arg) 2656 (setq target-arg-index (1+ target-arg-index))
2705 (setq target-arg-index (1+ target-arg-index)) 2657 (ad-get-argument
2706 (ad-get-argument 2658 source-arglist target-arg-index))
2707 source-arglist target-arg-index)))
2708 (append target-reqopt-args 2659 (append target-reqopt-args
2709 (and target-rest-arg 2660 (and target-rest-arg
2710 ;; If we have a rest arg gobble up 2661 ;; If we have a rest arg gobble up
@@ -2752,6 +2703,13 @@ Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2752(require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage. 2703(require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage.
2753 2704
2754(defun ad-make-advised-docstring (function &optional style) 2705(defun ad-make-advised-docstring (function &optional style)
2706 (let* ((origdef (ad-real-orig-definition function))
2707 (origdoc
2708 ;; Retrieve raw doc, key substitution will be taken care of later:
2709 (documentation origdef t)))
2710 (ad--make-advised-docstring origdoc function style)))
2711
2712(defun ad--make-advised-docstring (origdoc function &optional style)
2755 "Construct a documentation string for the advised FUNCTION. 2713 "Construct a documentation string for the advised FUNCTION.
2756It concatenates the original documentation with the documentation 2714It concatenates the original documentation with the documentation
2757strings of the individual pieces of advice which will be formatted 2715strings of the individual pieces of advice which will be formatted
@@ -2761,11 +2719,8 @@ strings corresponds to before/around/after and the individual ordering
2761in any of these classes." 2719in any of these classes."
2762 (let* ((origdef (ad-real-orig-definition function)) 2720 (let* ((origdef (ad-real-orig-definition function))
2763 (origtype (symbol-name (ad-definition-type origdef))) 2721 (origtype (symbol-name (ad-definition-type origdef)))
2764 (origdoc
2765 ;; Retrieve raw doc, key substitution will be taken care of later:
2766 (ad-real-documentation origdef t))
2767 (usage (help-split-fundoc origdoc function)) 2722 (usage (help-split-fundoc origdoc function))
2768 paragraphs advice-docstring ad-usage) 2723 paragraphs advice-docstring)
2769 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage))) 2724 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage)))
2770 (if origdoc (setq paragraphs (list origdoc))) 2725 (if origdoc (setq paragraphs (list origdoc)))
2771 (unless (eq style 'plain) 2726 (unless (eq style 'plain)
@@ -2780,7 +2735,9 @@ in any of these classes."
2780 (propertize 2735 (propertize
2781 ;; separate paragraphs with blank lines: 2736 ;; separate paragraphs with blank lines:
2782 (mapconcat 'identity (nreverse paragraphs) "\n\n") 2737 (mapconcat 'identity (nreverse paragraphs) "\n\n")
2783 'ad-advice-info function))) 2738 ;; FIXME: what is this for?
2739 'dynamic-docstring-function
2740 #'ad--make-advised-docstring)))
2784 (help-add-fundoc-usage origdoc usage))) 2741 (help-add-fundoc-usage origdoc usage)))
2785 2742
2786(defun ad-make-plain-docstring (function) 2743(defun ad-make-plain-docstring (function)
@@ -2823,10 +2780,10 @@ in any of these classes."
2823 (origname (ad-get-advice-info-field function 'origname)) 2780 (origname (ad-get-advice-info-field function 'origname))
2824 (orig-interactive-p (commandp origdef)) 2781 (orig-interactive-p (commandp origdef))
2825 (orig-subr-p (ad-subr-p origdef)) 2782 (orig-subr-p (ad-subr-p origdef))
2826 (orig-special-form-p (ad-special-form-p origdef)) 2783 (orig-special-form-p (special-form-p origdef))
2827 (orig-macro-p (ad-macro-p origdef)) 2784 (orig-macro-p (ad-macro-p origdef))
2828 ;; Construct the individual pieces that we need for assembly: 2785 ;; Construct the individual pieces that we need for assembly:
2829 (orig-arglist (ad-arglist origdef function)) 2786 (orig-arglist (ad-arglist origdef))
2830 (advised-arglist (or (ad-advised-arglist function) 2787 (advised-arglist (or (ad-advised-arglist function)
2831 orig-arglist)) 2788 orig-arglist))
2832 (advised-interactive-form (ad-advised-interactive-form function)) 2789 (advised-interactive-form (ad-advised-interactive-form function))
@@ -2921,8 +2878,8 @@ should be modified. The assembled function will be returned."
2921 (setq around-form-protected t)) 2878 (setq around-form-protected t))
2922 (setq around-form 2879 (setq around-form
2923 (ad-substitute-tree 2880 (ad-substitute-tree
2924 (function (lambda (form) (eq form 'ad-do-it))) 2881 (lambda (form) (eq form 'ad-do-it))
2925 (function (lambda (form) around-form)) 2882 (lambda (_form) around-form)
2926 (macroexp-progn (ad-body-forms (ad-advice-definition advice)))))) 2883 (macroexp-progn (ad-body-forms (ad-advice-definition advice))))))
2927 2884
2928 (setq after-forms 2885 (setq after-forms
@@ -3057,10 +3014,10 @@ advised definition from scratch."
3057 (mapcar (function (lambda (advice) (ad-advice-name advice))) 3014 (mapcar (function (lambda (advice) (ad-advice-name advice)))
3058 (ad-get-enabled-advices function 'after)) 3015 (ad-get-enabled-advices function 'after))
3059 (ad-definition-type original-definition) 3016 (ad-definition-type original-definition)
3060 (if (equal (ad-arglist original-definition function) 3017 (if (equal (ad-arglist original-definition)
3061 (ad-arglist cached-definition)) 3018 (ad-arglist cached-definition))
3062 t 3019 t
3063 (ad-arglist original-definition function)) 3020 (ad-arglist original-definition))
3064 (if (eq (ad-definition-type original-definition) 'function) 3021 (if (eq (ad-definition-type original-definition) 'function)
3065 (equal (interactive-form original-definition) 3022 (equal (interactive-form original-definition)
3066 (interactive-form cached-definition)))))) 3023 (interactive-form cached-definition))))))
@@ -3105,7 +3062,7 @@ advised definition from scratch."
3105 (and (eq (nth 3 cache-id) (ad-definition-type original-definition)) 3062 (and (eq (nth 3 cache-id) (ad-definition-type original-definition))
3106 (setq code 'arglist-mismatch) 3063 (setq code 'arglist-mismatch)
3107 (equal (if (eq (nth 4 cache-id) t) 3064 (equal (if (eq (nth 4 cache-id) t)
3108 (ad-arglist original-definition function) 3065 (ad-arglist original-definition)
3109 (nth 4 cache-id) ) 3066 (nth 4 cache-id) )
3110 (ad-arglist cached-definition)) 3067 (ad-arglist cached-definition))
3111 (setq code 'interactive-form-mismatch) 3068 (setq code 'interactive-form-mismatch)
@@ -3164,7 +3121,7 @@ advised definition from scratch."
3164 (ad-set-advice-info function old-advice-info) 3121 (ad-set-advice-info function old-advice-info)
3165 ;; Don't `fset' function to nil if it was previously unbound: 3122 ;; Don't `fset' function to nil if it was previously unbound:
3166 (if function-defined-p 3123 (if function-defined-p
3167 (ad-safe-fset function old-definition) 3124 (fset function old-definition)
3168 (fmakunbound function))))) 3125 (fmakunbound function)))))
3169 3126
3170 3127
@@ -3195,61 +3152,54 @@ advised definition from scratch."
3195 (error 3152 (error
3196 "ad-make-freeze-definition: `%s' is not yet defined" 3153 "ad-make-freeze-definition: `%s' is not yet defined"
3197 function)) 3154 function))
3198 (let* ((name (ad-advice-name advice)) 3155 (cl-letf*
3199 ;; With a unique origname we can have multiple freeze advices 3156 ((name (ad-advice-name advice))
3200 ;; for the same function, each overloading the previous one: 3157 ;; With a unique origname we can have multiple freeze advices
3201 (unique-origname 3158 ;; for the same function, each overloading the previous one:
3202 (intern (format "%s-%s-%s" (ad-make-origname function) class name))) 3159 (unique-origname
3203 (orig-definition 3160 (intern (format "%s-%s-%s" (ad-make-origname function) class name)))
3204 ;; If FUNCTION is already advised, we'll use its current origdef 3161 (orig-definition
3205 ;; as the original definition of the frozen advice: 3162 ;; If FUNCTION is already advised, we'll use its current origdef
3206 (or (ad-get-orig-definition function) 3163 ;; as the original definition of the frozen advice:
3207 (symbol-function function))) 3164 (or (ad-get-orig-definition function)
3208 (old-advice-info 3165 (symbol-function function)))
3209 (if (ad-is-advised function) 3166 (old-advice-info
3210 (ad-copy-advice-info function))) 3167 (if (ad-is-advised function)
3211 (real-docstring-fn 3168 (ad-copy-advice-info function)))
3212 (symbol-function 'ad-make-advised-definition-docstring)) 3169 ;; Make sure we construct a proper docstring:
3213 (real-origname-fn 3170 ((symbol-function 'ad-make-advised-definition-docstring)
3214 (symbol-function 'ad-make-origname)) 3171 #'ad-make-freeze-docstring)
3215 (frozen-definition 3172 ;; Make sure `unique-origname' is used as the origname:
3216 (unwind-protect 3173 ((symbol-function 'ad-make-origname) (lambda (_x) unique-origname))
3217 (progn 3174 (frozen-definition
3218 ;; Make sure we construct a proper docstring: 3175 (unwind-protect
3219 (ad-safe-fset 'ad-make-advised-definition-docstring 3176 (progn
3220 'ad-make-freeze-docstring) 3177 ;; No we reset all current advice information to nil and
3221 ;; Make sure `unique-origname' is used as the origname: 3178 ;; generate an advised definition that's solely determined
3222 (ad-safe-fset 'ad-make-origname (lambda (x) unique-origname)) 3179 ;; by ADVICE and the current origdef of FUNCTION:
3223 ;; No we reset all current advice information to nil and 3180 (ad-set-advice-info function nil)
3224 ;; generate an advised definition that's solely determined 3181 (ad-add-advice function advice class position)
3225 ;; by ADVICE and the current origdef of FUNCTION: 3182 ;; The following will provide proper real docstrings as
3226 (ad-set-advice-info function nil) 3183 ;; well as a definition that will make the compiler happy:
3227 (ad-add-advice function advice class position) 3184 (ad-set-orig-definition function orig-definition)
3228 ;; The following will provide proper real docstrings as 3185 (ad-make-advised-definition function))
3229 ;; well as a definition that will make the compiler happy: 3186 ;; Restore the old advice state:
3230 (ad-set-orig-definition function orig-definition) 3187 (ad-set-advice-info function old-advice-info))))
3231 (ad-make-advised-definition function))
3232 ;; Restore the old advice state:
3233 (ad-set-advice-info function old-advice-info)
3234 ;; Restore functions:
3235 (ad-safe-fset
3236 'ad-make-advised-definition-docstring real-docstring-fn)
3237 (ad-safe-fset 'ad-make-origname real-origname-fn))))
3238 (if frozen-definition 3188 (if frozen-definition
3239 (let* ((macro-p (ad-macro-p frozen-definition)) 3189 (let* ((macro-p (ad-macro-p frozen-definition))
3240 (body (cdr (if macro-p 3190 (body (cdr (if macro-p
3241 (ad-lambdafy frozen-definition) 3191 (ad-lambdafy frozen-definition)
3242 frozen-definition)))) 3192 frozen-definition))))
3243 `(progn 3193 `(progn
3244 (if (not (fboundp ',unique-origname)) 3194 (if (not (fboundp ',unique-origname))
3245 (fset ',unique-origname 3195 (fset ',unique-origname
3246 ;; avoid infinite recursion in case the function 3196 ;; avoid infinite recursion in case the function
3247 ;; we want to freeze is already advised: 3197 ;; we want to freeze is already advised:
3248 (or (ad-get-orig-definition ',function) 3198 (or (ad-get-orig-definition ',function)
3249 (symbol-function ',function)))) 3199 (symbol-function ',function))))
3250 (,(if macro-p 'defmacro 'defun) 3200 (,(if macro-p 'defmacro 'defun)
3251 ,function 3201 ,function
3252 ,@body)))))) 3202 ,@body))))))
3253 3203
3254 3204
3255;; @@ Activation and definition handling: 3205;; @@ Activation and definition handling:
@@ -3282,7 +3232,7 @@ The current definition and its cache-id will be put into the cache."
3282 (let ((verified-cached-definition 3232 (let ((verified-cached-definition
3283 (if (ad-verify-cache-id function) 3233 (if (ad-verify-cache-id function)
3284 (ad-get-cache-definition function)))) 3234 (ad-get-cache-definition function))))
3285 (ad-safe-fset function 3235 (fset function
3286 (or verified-cached-definition 3236 (or verified-cached-definition
3287 (ad-make-advised-definition function))) 3237 (ad-make-advised-definition function)))
3288 (if (ad-should-compile function compile) 3238 (if (ad-should-compile function compile)
@@ -3324,7 +3274,7 @@ the value of `ad-redefinition-action' and de/activate again."
3324 (error "ad-handle-definition (see its doc): `%s' %s" 3274 (error "ad-handle-definition (see its doc): `%s' %s"
3325 function "invalidly redefined") 3275 function "invalidly redefined")
3326 (if (eq ad-redefinition-action 'discard) 3276 (if (eq ad-redefinition-action 'discard)
3327 (ad-safe-fset function original-definition) 3277 (fset function original-definition)
3328 (ad-set-orig-definition function current-definition) 3278 (ad-set-orig-definition function current-definition)
3329 (if (eq ad-redefinition-action 'warn) 3279 (if (eq ad-redefinition-action 'warn)
3330 (message "ad-handle-definition: `%s' got redefined" 3280 (message "ad-handle-definition: `%s' got redefined"
@@ -3399,7 +3349,7 @@ a call to `ad-activate'."
3399 (if (not (ad-get-orig-definition function)) 3349 (if (not (ad-get-orig-definition function))
3400 (error "ad-deactivate: `%s' has no original definition" 3350 (error "ad-deactivate: `%s' has no original definition"
3401 function) 3351 function)
3402 (ad-safe-fset function (ad-get-orig-definition function)) 3352 (fset function (ad-get-orig-definition function))
3403 (ad-set-advice-info-field function 'active nil) 3353 (ad-set-advice-info-field function 'active nil)
3404 (eval (ad-make-hook-form function 'deactivation)) 3354 (eval (ad-make-hook-form function 'deactivation))
3405 function))))) 3355 function)))))
@@ -3437,7 +3387,7 @@ Use in emergencies."
3437 (completing-read "Recover advised function: " obarray nil t)))) 3387 (completing-read "Recover advised function: " obarray nil t))))
3438 (cond ((ad-is-advised function) 3388 (cond ((ad-is-advised function)
3439 (cond ((ad-get-orig-definition function) 3389 (cond ((ad-get-orig-definition function)
3440 (ad-safe-fset function (ad-get-orig-definition function)) 3390 (fset function (ad-get-orig-definition function))
3441 (ad-clear-orig-definition function))) 3391 (ad-clear-orig-definition function)))
3442 (ad-set-advice-info function nil) 3392 (ad-set-advice-info function nil)
3443 (ad-pop-advised-function function)))) 3393 (ad-pop-advised-function function))))
@@ -3669,28 +3619,22 @@ undone on exit of this macro."
3669 ;; Make forms to redefine functions to their 3619 ;; Make forms to redefine functions to their
3670 ;; original definitions if they are advised: 3620 ;; original definitions if they are advised:
3671 (setq index -1) 3621 (setq index -1)
3672 (mapcar 3622 (mapcar (lambda (function)
3673 (function 3623 (setq index (1+ index))
3674 (lambda (function) 3624 `(fset ',function
3675 (setq index (1+ index)) 3625 (or (ad-get-orig-definition ',function)
3676 `(ad-safe-fset 3626 ,(car (nth index current-bindings)))))
3677 ',function 3627 functions))
3678 (or (ad-get-orig-definition ',function)
3679 ,(car (nth index current-bindings))))))
3680 functions))
3681 ,@body) 3628 ,@body)
3682 ,@(progn 3629 ,@(progn
3683 ;; Make forms to back-define functions to the definitions 3630 ;; Make forms to back-define functions to the definitions
3684 ;; they had outside this macro call: 3631 ;; they had outside this macro call:
3685 (setq index -1) 3632 (setq index -1)
3686 (mapcar 3633 (mapcar (lambda (function)
3687 (function 3634 (setq index (1+ index))
3688 (lambda (function) 3635 `(fset ',function
3689 (setq index (1+ index)) 3636 ,(car (nth index current-bindings))))
3690 `(ad-safe-fset 3637 functions))))))
3691 ',function
3692 ,(car (nth index current-bindings)))))
3693 functions))))))
3694 3638
3695 3639
3696;; @@ Starting, stopping and recovering from the advice package magic: 3640;; @@ Starting, stopping and recovering from the advice package magic:
@@ -3701,7 +3645,7 @@ undone on exit of this macro."
3701 (interactive) 3645 (interactive)
3702 ;; Advising `ad-activate-internal' means death!! 3646 ;; Advising `ad-activate-internal' means death!!
3703 (ad-set-advice-info 'ad-activate-internal nil) 3647 (ad-set-advice-info 'ad-activate-internal nil)
3704 (ad-safe-fset 'ad-activate-internal 'ad-activate)) 3648 (fset 'ad-activate-internal 'ad-activate))
3705 3649
3706(defun ad-stop-advice () 3650(defun ad-stop-advice ()
3707 "Stop the automatic advice handling magic. 3651 "Stop the automatic advice handling magic.
@@ -3709,7 +3653,7 @@ You should only need this in case of Advice-related emergencies."
3709 (interactive) 3653 (interactive)
3710 ;; Advising `ad-activate-internal' means death!! 3654 ;; Advising `ad-activate-internal' means death!!
3711 (ad-set-advice-info 'ad-activate-internal nil) 3655 (ad-set-advice-info 'ad-activate-internal nil)
3712 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off)) 3656 (fset 'ad-activate-internal 'ad-activate-internal-off))
3713 3657
3714(defun ad-recover-normality () 3658(defun ad-recover-normality ()
3715 "Undo all advice related redefinitions and unadvises everything. 3659 "Undo all advice related redefinitions and unadvises everything.
@@ -3717,9 +3661,11 @@ Use only in REAL emergencies."
3717 (interactive) 3661 (interactive)
3718 ;; Advising `ad-activate-internal' means death!! 3662 ;; Advising `ad-activate-internal' means death!!
3719 (ad-set-advice-info 'ad-activate-internal nil) 3663 (ad-set-advice-info 'ad-activate-internal nil)
3720 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off) 3664 (fset 'ad-activate-internal 'ad-activate-internal-off)
3721 (ad-recover-all) 3665 (ad-recover-all)
3722 (setq ad-advised-functions nil)) 3666 (ad-do-advised-functions (function)
3667 (message "Oops! Left over advised function %S" function)
3668 (ad-pop-advised-function function)))
3723 3669
3724(ad-start-advice) 3670(ad-start-advice)
3725 3671
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index e776df4ef37..a325e0f3e44 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -419,8 +419,8 @@ This list lives partly on the stack.")
419 419
420(defconst byte-compile-initial-macro-environment 420(defconst byte-compile-initial-macro-environment
421 '( 421 '(
422;; (byte-compiler-options . (lambda (&rest forms) 422 ;; (byte-compiler-options . (lambda (&rest forms)
423;; (apply 'byte-compiler-options-handler forms))) 423 ;; (apply 'byte-compiler-options-handler forms)))
424 (declare-function . byte-compile-macroexpand-declare-function) 424 (declare-function . byte-compile-macroexpand-declare-function)
425 (eval-when-compile . (lambda (&rest body) 425 (eval-when-compile . (lambda (&rest body)
426 (list 426 (list
@@ -429,8 +429,19 @@ This list lives partly on the stack.")
429 (byte-compile-top-level 429 (byte-compile-top-level
430 (byte-compile-preprocess (cons 'progn body))))))) 430 (byte-compile-preprocess (cons 'progn body)))))))
431 (eval-and-compile . (lambda (&rest body) 431 (eval-and-compile . (lambda (&rest body)
432 (byte-compile-eval-before-compile (cons 'progn body)) 432 ;; Byte compile before running it. Do it piece by
433 (cons 'progn body)))) 433 ;; piece, in case further expressions need earlier
434 ;; ones to be evaluated already, as is the case in
435 ;; eieio.el.
436 `(progn
437 ,@(mapcar (lambda (exp)
438 (let ((cexp
439 (byte-compile-top-level
440 (byte-compile-preprocess
441 exp))))
442 (eval cexp)
443 cexp))
444 body)))))
434 "The default macro-environment passed to macroexpand by the compiler. 445 "The default macro-environment passed to macroexpand by the compiler.
435Placing a macro here will cause a macro to have different semantics when 446Placing a macro here will cause a macro to have different semantics when
436expanded by the compiler as when expanded by the interpreter.") 447expanded by the compiler as when expanded by the interpreter.")
@@ -731,9 +742,11 @@ otherwise pop it")
731;; Also, this lets us notice references to free variables. 742;; Also, this lets us notice references to free variables.
732 743
733(defmacro byte-compile-push-bytecodes (&rest args) 744(defmacro byte-compile-push-bytecodes (&rest args)
734 "Push BYTE... onto BYTES, and increment PC by the number of bytes pushed. 745 "Push bytes onto BVAR, and increment CVAR by the number of bytes pushed.
735ARGS is of the form (BYTE... BYTES PC), where BYTES and PC are variable names. 746BVAR and CVAR are variables which are updated after evaluating
736BYTES and PC are updated after evaluating all the arguments." 747all the arguments.
748
749\(fn BYTE1 BYTE2 ... BYTEn BVAR CVAR)"
737 (let ((byte-exprs (butlast args 2)) 750 (let ((byte-exprs (butlast args 2))
738 (bytes-var (car (last args 2))) 751 (bytes-var (car (last args 2)))
739 (pc-var (car (last args)))) 752 (pc-var (car (last args))))
@@ -1097,8 +1110,7 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'."
1097(defun byte-compile-log-warning (string &optional fill level) 1110(defun byte-compile-log-warning (string &optional fill level)
1098 (let ((warning-prefix-function 'byte-compile-warning-prefix) 1111 (let ((warning-prefix-function 'byte-compile-warning-prefix)
1099 (warning-type-format "") 1112 (warning-type-format "")
1100 (warning-fill-prefix (if fill " ")) 1113 (warning-fill-prefix (if fill " ")))
1101 (inhibit-read-only t))
1102 (display-warning 'bytecomp string level byte-compile-log-buffer))) 1114 (display-warning 'bytecomp string level byte-compile-log-buffer)))
1103 1115
1104(defun byte-compile-warn (format &rest args) 1116(defun byte-compile-warn (format &rest args)
@@ -2189,7 +2201,10 @@ list that represents a doc string reference.
2189 (when (and (consp (nth 1 form)) 2201 (when (and (consp (nth 1 form))
2190 (eq (car (nth 1 form)) 'quote) 2202 (eq (car (nth 1 form)) 'quote)
2191 (consp (cdr (nth 1 form))) 2203 (consp (cdr (nth 1 form)))
2192 (symbolp (nth 1 (nth 1 form)))) 2204 (symbolp (nth 1 (nth 1 form)))
2205 ;; Don't add it if it's already defined. Otherwise, it might
2206 ;; hide the actual definition.
2207 (not (fboundp (nth 1 (nth 1 form)))))
2193 (push (cons (nth 1 (nth 1 form)) 2208 (push (cons (nth 1 (nth 1 form))
2194 (cons 'autoload (cdr (cdr form)))) 2209 (cons 'autoload (cdr (cdr form))))
2195 byte-compile-function-environment) 2210 byte-compile-function-environment)
@@ -2808,7 +2823,8 @@ for symbols generated by the byte compiler itself."
2808 (setq body (nreverse body)) 2823 (setq body (nreverse body))
2809 (setq body (list 2824 (setq body (list
2810 (if (and (eq tmp 'funcall) 2825 (if (and (eq tmp 'funcall)
2811 (eq (car-safe (car body)) 'quote)) 2826 (eq (car-safe (car body)) 'quote)
2827 (symbolp (nth 1 (car body))))
2812 (cons (nth 1 (car body)) (cdr body)) 2828 (cons (nth 1 (car body)) (cdr body))
2813 (cons tmp body)))) 2829 (cons tmp body))))
2814 (or (eq output-type 'file) 2830 (or (eq output-type 'file)
@@ -3689,10 +3705,10 @@ If CONDITION's value is (not (featurep 'emacs)) or (featurep 'xemacs),
3689that suppresses all warnings during execution of BODY." 3705that suppresses all warnings during execution of BODY."
3690 (declare (indent 1) (debug t)) 3706 (declare (indent 1) (debug t))
3691 `(let* ((fbound-list (byte-compile-find-bound-condition 3707 `(let* ((fbound-list (byte-compile-find-bound-condition
3692 ,condition (list 'fboundp) 3708 ,condition '(fboundp functionp)
3693 byte-compile-unresolved-functions)) 3709 byte-compile-unresolved-functions))
3694 (bound-list (byte-compile-find-bound-condition 3710 (bound-list (byte-compile-find-bound-condition
3695 ,condition (list 'boundp 'default-boundp))) 3711 ,condition '(boundp default-boundp)))
3696 ;; Maybe add to the bound list. 3712 ;; Maybe add to the bound list.
3697 (byte-compile-bound-variables 3713 (byte-compile-bound-variables
3698 (append bound-list byte-compile-bound-variables))) 3714 (append bound-list byte-compile-bound-variables)))
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index a57de344cf3..7c25972835b 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -131,7 +131,7 @@ TYPE is the sequence type to return.
131;;;###autoload 131;;;###autoload
132(defun cl-maplist (cl-func cl-list &rest cl-rest) 132(defun cl-maplist (cl-func cl-list &rest cl-rest)
133 "Map FUNCTION to each sublist of LIST or LISTs. 133 "Map FUNCTION to each sublist of LIST or LISTs.
134Like `mapcar', except applies to lists and their cdr's rather than to 134Like `cl-mapcar', except applies to lists and their cdr's rather than to
135the elements themselves. 135the elements themselves.
136\n(fn FUNCTION LIST...)" 136\n(fn FUNCTION LIST...)"
137 (if cl-rest 137 (if cl-rest
@@ -170,7 +170,7 @@ the elements themselves.
170 170
171;;;###autoload 171;;;###autoload
172(defun cl-mapcan (cl-func cl-seq &rest cl-rest) 172(defun cl-mapcan (cl-func cl-seq &rest cl-rest)
173 "Like `mapcar', but nconc's together the values returned by the function. 173 "Like `cl-mapcar', but nconc's together the values returned by the function.
174\n(fn FUNCTION SEQUENCE...)" 174\n(fn FUNCTION SEQUENCE...)"
175 (apply 'nconc (apply 'cl-mapcar cl-func cl-seq cl-rest))) 175 (apply 'nconc (apply 'cl-mapcar cl-func cl-seq cl-rest)))
176 176
@@ -675,6 +675,9 @@ PROPLIST is a list of the sort returned by `symbol-plist'.
675 675
676;;;###autoload 676;;;###autoload
677(defun cl-prettyexpand (form &optional full) 677(defun cl-prettyexpand (form &optional full)
678 "Expand macros in FORM and insert the pretty-printed result.
679Optional argument FULL non-nil means to expand all macros,
680including `cl-block' and `cl-eval-when'."
678 (message "Expanding...") 681 (message "Expanding...")
679 (let ((cl--compiling-file full) 682 (let ((cl--compiling-file full)
680 (byte-compile-macro-environment nil)) 683 (byte-compile-macro-environment nil))
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 034a5c7517e..a9be08b1383 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -251,12 +251,17 @@ one value.
251(defvar cl-proclaims-deferred nil) 251(defvar cl-proclaims-deferred nil)
252 252
253(defun cl-proclaim (spec) 253(defun cl-proclaim (spec)
254 "Record a global declaration specified by SPEC."
254 (if (fboundp 'cl-do-proclaim) (cl-do-proclaim spec t) 255 (if (fboundp 'cl-do-proclaim) (cl-do-proclaim spec t)
255 (push spec cl-proclaims-deferred)) 256 (push spec cl-proclaims-deferred))
256 nil) 257 nil)
257 258
258(defmacro cl-declaim (&rest specs) 259(defmacro cl-declaim (&rest specs)
259 (let ((body (mapcar (function (lambda (x) (list 'cl-proclaim (list 'quote x)))) 260 "Like `cl-proclaim', but takes any number of unevaluated, unquoted arguments.
261Puts `(cl-eval-when (compile load eval) ...)' around the declarations
262so that they are registered at compile-time as well as run-time."
263 (let ((body (mapcar (function (lambda (x)
264 (list 'cl-proclaim (list 'quote x))))
260 specs))) 265 specs)))
261 (if (cl--compiling-file) (cl-list* 'cl-eval-when '(compile load eval) body) 266 (if (cl--compiling-file) (cl-list* 'cl-eval-when '(compile load eval) body)
262 (cons 'progn body)))) ; avoid loading cl-macs.el for cl-eval-when 267 (cons 'progn body)))) ; avoid loading cl-macs.el for cl-eval-when
diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el
index 5687f92083f..bf99af2f7e6 100644
--- a/lisp/emacs-lisp/cl-loaddefs.el
+++ b/lisp/emacs-lisp/cl-loaddefs.el
@@ -11,7 +11,7 @@
11;;;;;; cl--map-overlays cl--map-intervals cl--map-keymap-recursively 11;;;;;; cl--map-overlays cl--map-intervals cl--map-keymap-recursively
12;;;;;; cl-notevery cl-notany cl-every cl-some cl-mapcon cl-mapcan 12;;;;;; cl-notevery cl-notany cl-every cl-some cl-mapcon cl-mapcan
13;;;;;; cl-mapl cl-mapc cl-maplist cl-map cl--mapcar-many cl-equalp 13;;;;;; cl-mapl cl-mapc cl-maplist cl-map cl--mapcar-many cl-equalp
14;;;;;; cl-coerce) "cl-extra" "cl-extra.el" "0e9284b6492cc98eee7c85ae4e5322ee") 14;;;;;; cl-coerce) "cl-extra" "cl-extra.el" "8e9fee941c465ac0fee9b92a92d64154")
15;;; Generated autoloads from cl-extra.el 15;;; Generated autoloads from cl-extra.el
16 16
17(autoload 'cl-coerce "cl-extra" "\ 17(autoload 'cl-coerce "cl-extra" "\
@@ -41,7 +41,7 @@ TYPE is the sequence type to return.
41 41
42(autoload 'cl-maplist "cl-extra" "\ 42(autoload 'cl-maplist "cl-extra" "\
43Map FUNCTION to each sublist of LIST or LISTs. 43Map FUNCTION to each sublist of LIST or LISTs.
44Like `mapcar', except applies to lists and their cdr's rather than to 44Like `cl-mapcar', except applies to lists and their cdr's rather than to
45the elements themselves. 45the elements themselves.
46 46
47\(fn FUNCTION LIST...)" nil nil) 47\(fn FUNCTION LIST...)" nil nil)
@@ -57,7 +57,7 @@ Like `cl-maplist', but does not accumulate values returned by the function.
57\(fn FUNCTION LIST...)" nil nil) 57\(fn FUNCTION LIST...)" nil nil)
58 58
59(autoload 'cl-mapcan "cl-extra" "\ 59(autoload 'cl-mapcan "cl-extra" "\
60Like `mapcar', but nconc's together the values returned by the function. 60Like `cl-mapcar', but nconc's together the values returned by the function.
61 61
62\(fn FUNCTION SEQUENCE...)" nil nil) 62\(fn FUNCTION SEQUENCE...)" nil nil)
63 63
@@ -248,7 +248,9 @@ Remove from SYMBOL's plist the property PROPNAME and its value.
248\(fn SYMBOL PROPNAME)" nil nil) 248\(fn SYMBOL PROPNAME)" nil nil)
249 249
250(autoload 'cl-prettyexpand "cl-extra" "\ 250(autoload 'cl-prettyexpand "cl-extra" "\
251 251Expand macros in FORM and insert the pretty-printed result.
252Optional argument FULL non-nil means to expand all macros,
253including `cl-block' and `cl-eval-when'.
252 254
253\(fn FORM &optional FULL)" nil nil) 255\(fn FORM &optional FULL)" nil nil)
254 256
@@ -265,7 +267,7 @@ Remove from SYMBOL's plist the property PROPNAME and its value.
265;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when 267;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when
266;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp 268;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp
267;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*) 269;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*)
268;;;;;; "cl-macs" "cl-macs.el" "146e82321e05b9e3fe8c70d7dbbab8a6") 270;;;;;; "cl-macs" "cl-macs.el" "a7228877484d2b39e1c2bee40b011734")
269;;; Generated autoloads from cl-macs.el 271;;; Generated autoloads from cl-macs.el
270 272
271(autoload 'cl--compiler-macro-list* "cl-macs" "\ 273(autoload 'cl--compiler-macro-list* "cl-macs" "\
@@ -320,7 +322,7 @@ its argument list allows full Common Lisp conventions.
320\(fn FUNC)" nil t) 322\(fn FUNC)" nil t)
321 323
322(autoload 'cl-destructuring-bind "cl-macs" "\ 324(autoload 'cl-destructuring-bind "cl-macs" "\
323 325Bind the variables in ARGS to the result of EXPR and execute BODY.
324 326
325\(fn ARGS EXPR &rest BODY)" nil t) 327\(fn ARGS EXPR &rest BODY)" nil t)
326 328
@@ -564,12 +566,12 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C).
564(put 'cl-multiple-value-setq 'lisp-indent-function '1) 566(put 'cl-multiple-value-setq 'lisp-indent-function '1)
565 567
566(autoload 'cl-locally "cl-macs" "\ 568(autoload 'cl-locally "cl-macs" "\
567 569Equivalent to `progn'.
568 570
569\(fn &rest BODY)" nil t) 571\(fn &rest BODY)" nil t)
570 572
571(autoload 'cl-the "cl-macs" "\ 573(autoload 'cl-the "cl-macs" "\
572 574At present this ignores _TYPE and is simply equivalent to FORM.
573 575
574\(fn TYPE FORM)" nil t) 576\(fn TYPE FORM)" nil t)
575 577
@@ -721,7 +723,10 @@ and then returning foo.
721\(fn FUNC ARGS &rest BODY)" nil t) 723\(fn FUNC ARGS &rest BODY)" nil t)
722 724
723(autoload 'cl-compiler-macroexpand "cl-macs" "\ 725(autoload 'cl-compiler-macroexpand "cl-macs" "\
724 726Like `macroexpand', but for compiler macros.
727Expands FORM repeatedly until no further expansion is possible.
728Returns FORM unchanged if it has no compiler macro, or if it has a
729macro that returns its `&whole' argument.
725 730
726\(fn FORM)" nil nil) 731\(fn FORM)" nil nil)
727 732
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index cd537cd43d6..f3bf36de376 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -554,6 +554,7 @@ its argument list allows full Common Lisp conventions."
554 554
555;;;###autoload 555;;;###autoload
556(defmacro cl-destructuring-bind (args expr &rest body) 556(defmacro cl-destructuring-bind (args expr &rest body)
557 "Bind the variables in ARGS to the result of EXPR and execute BODY."
557 (declare (indent 2) 558 (declare (indent 2)
558 (debug (&define cl-macro-list def-form cl-declarations def-body))) 559 (debug (&define cl-macro-list def-form cl-declarations def-body)))
559 (let* ((cl--bind-lets nil) (cl--bind-forms nil) (cl--bind-inits nil) 560 (let* ((cl--bind-lets nil) (cl--bind-forms nil) (cl--bind-inits nil)
@@ -1886,10 +1887,12 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C).
1886 1887
1887;;;###autoload 1888;;;###autoload
1888(defmacro cl-locally (&rest body) 1889(defmacro cl-locally (&rest body)
1890 "Equivalent to `progn'."
1889 (declare (debug t)) 1891 (declare (debug t))
1890 (cons 'progn body)) 1892 (cons 'progn body))
1891;;;###autoload 1893;;;###autoload
1892(defmacro cl-the (_type form) 1894(defmacro cl-the (_type form)
1895 "At present this ignores _TYPE and is simply equivalent to FORM."
1893 (declare (indent 1) (debug (cl-type-spec form))) 1896 (declare (indent 1) (debug (cl-type-spec form)))
1894 form) 1897 form)
1895 1898
@@ -2537,6 +2540,10 @@ and then returning foo."
2537 2540
2538;;;###autoload 2541;;;###autoload
2539(defun cl-compiler-macroexpand (form) 2542(defun cl-compiler-macroexpand (form)
2543 "Like `macroexpand', but for compiler macros.
2544Expands FORM repeatedly until no further expansion is possible.
2545Returns FORM unchanged if it has no compiler macro, or if it has a
2546macro that returns its `&whole' argument."
2540 (while 2547 (while
2541 (let ((func (car-safe form)) (handler nil)) 2548 (let ((func (car-safe form)) (handler nil))
2542 (while (and (symbolp func) 2549 (while (and (symbolp func)
diff --git a/lisp/emacs-lisp/cl.el b/lisp/emacs-lisp/cl.el
index c5d0edf2009..3fb5b227c73 100644
--- a/lisp/emacs-lisp/cl.el
+++ b/lisp/emacs-lisp/cl.el
@@ -547,13 +547,15 @@ deprecated usage of `symbol-function' in place forms)." ; bug#12760
547 547
548(defmacro define-setf-expander (name arglist &rest body) 548(defmacro define-setf-expander (name arglist &rest body)
549 "Define a `setf' method. 549 "Define a `setf' method.
550This method shows how to handle `setf's to places of the form (NAME ARGS...). 550This method shows how to handle `setf's to places of the form
551The argument forms ARGS are bound according to ARGLIST, as if NAME were 551\(NAME ARGS...). The argument forms ARGS are bound according to
552going to be expanded as a macro, then the BODY forms are executed and must 552ARGLIST, as if NAME were going to be expanded as a macro, then
553return a list of five elements: a temporary-variables list, a value-forms 553the BODY forms are executed and must return a list of five elements:
554list, a store-variables list (of length one), a store-form, and an access- 554a temporary-variables list, a value-forms list, a store-variables list
555form. See `gv-define-expander', `gv-define-setter', and `gv-define-expander' 555\(of length one), a store-form, and an access- form.
556for a better and simpler ways to define setf-methods." 556
557See `gv-define-expander', and `gv-define-setter' for better and
558simpler ways to define setf-methods."
557 (declare (debug 559 (declare (debug
558 (&define name cl-lambda-list cl-declarations-or-string def-body))) 560 (&define name cl-lambda-list cl-declarations-or-string def-body)))
559 `(progn 561 `(progn
@@ -566,23 +568,31 @@ for a better and simpler ways to define setf-methods."
566 568
567(defmacro defsetf (name arg1 &rest args) 569(defmacro defsetf (name arg1 &rest args)
568 "Define a `setf' method. 570 "Define a `setf' method.
569This macro is an easy-to-use substitute for `define-setf-expander' that works 571This macro is an easy-to-use substitute for `define-setf-expander'
570well for simple place forms. In the simple `defsetf' form, `setf's of 572that works well for simple place forms.
571the form (setf (NAME ARGS...) VAL) are transformed to function or macro 573
572calls of the form (FUNC ARGS... VAL). Example: 574In the simple `defsetf' form, `setf's of the form (setf (NAME
575ARGS...) VAL) are transformed to function or macro calls of the
576form (FUNC ARGS... VAL). For example:
573 577
574 (defsetf aref aset) 578 (defsetf aref aset)
575 579
580You can replace this form with `gv-define-simple-setter'.
581
576Alternate form: (defsetf NAME ARGLIST (STORE) BODY...). 582Alternate form: (defsetf NAME ARGLIST (STORE) BODY...).
577Here, the above `setf' call is expanded by binding the argument forms ARGS 583
578according to ARGLIST, binding the value form VAL to STORE, then executing 584Here, the above `setf' call is expanded by binding the argument
579BODY, which must return a Lisp form that does the necessary `setf' operation. 585forms ARGS according to ARGLIST, binding the value form VAL to
580Actually, ARGLIST and STORE may be bound to temporary variables which are 586STORE, then executing BODY, which must return a Lisp form that
581introduced automatically to preserve proper execution order of the arguments. 587does the necessary `setf' operation. Actually, ARGLIST and STORE
582Example: 588may be bound to temporary variables which are introduced
589automatically to preserve proper execution order of the arguments.
590For example:
583 591
584 (defsetf nth (n x) (v) `(setcar (nthcdr ,n ,x) ,v)) 592 (defsetf nth (n x) (v) `(setcar (nthcdr ,n ,x) ,v))
585 593
594You can replace this form with `gv-define-setter'.
595
586\(fn NAME [FUNC | ARGLIST (STORE) BODY...])" 596\(fn NAME [FUNC | ARGLIST (STORE) BODY...])"
587 (declare (debug 597 (declare (debug
588 (&define name 598 (&define name
@@ -597,7 +607,7 @@ Example:
597 (cl-function 607 (cl-function
598 (lambda (,@(car args) ,@arg1) ,@(cdr args))) 608 (lambda (,@(car args) ,@arg1) ,@(cdr args)))
599 do args))) 609 do args)))
600 `(gv-define-simple-setter ,name ,arg1))) 610 `(gv-define-simple-setter ,name ,arg1 ,(car args))))
601 611
602;; FIXME: CL used to provide a setf method for `apply', but I haven't been able 612;; FIXME: CL used to provide a setf method for `apply', but I haven't been able
603;; to find a case where it worked. The code below tries to handle it as well. 613;; to find a case where it worked. The code below tries to handle it as well.
@@ -639,8 +649,12 @@ Example:
639 649
640(defmacro define-modify-macro (name arglist func &optional doc) 650(defmacro define-modify-macro (name arglist func &optional doc)
641 "Define a `setf'-like modify macro. 651 "Define a `setf'-like modify macro.
642If NAME is called, it combines its PLACE argument with the other arguments 652If NAME is called, it combines its PLACE argument with the other
643from ARGLIST using FUNC: (define-modify-macro incf (&optional (n 1)) +)" 653arguments from ARGLIST using FUNC. For example:
654
655 (define-modify-macro incf (&optional (n 1)) +)
656
657You can replace this macro with `gv-letplace'."
644 (declare (debug 658 (declare (debug
645 (&define name cl-lambda-list ;; should exclude &key 659 (&define name cl-lambda-list ;; should exclude &key
646 symbolp &optional stringp))) 660 symbolp &optional stringp)))
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index c04e68c0cfa..3d4f41be8ee 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -1,4 +1,4 @@
1;;; debug.el --- debuggers and related commands for Emacs 1;;; debug.el --- debuggers and related commands for Emacs -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 1985-1986, 1994, 2001-2012 Free Software Foundation, Inc. 3;; Copyright (C) 1985-1986, 1994, 2001-2012 Free Software Foundation, Inc.
4 4
@@ -81,9 +81,6 @@ The value used here is passed to `quit-restore-window'."
81 :group 'debugger 81 :group 'debugger
82 :version "24.2") 82 :version "24.2")
83 83
84(defvar debug-function-list nil
85 "List of functions currently set for debug on entry.")
86
87(defvar debugger-step-after-exit nil 84(defvar debugger-step-after-exit nil
88 "Non-nil means \"single-step\" after the debugger exits.") 85 "Non-nil means \"single-step\" after the debugger exits.")
89 86
@@ -146,7 +143,7 @@ where CAUSE can be:
146;;;###autoload 143;;;###autoload
147(setq debugger 'debug) 144(setq debugger 'debug)
148;;;###autoload 145;;;###autoload
149(defun debug (&rest debugger-args) 146(defun debug (&rest args)
150 "Enter debugger. \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger. 147 "Enter debugger. \\<debugger-mode-map>`\\[debugger-continue]' returns from the debugger.
151Arguments are mainly for use when this is called from the internals 148Arguments are mainly for use when this is called from the internals
152of the evaluator. 149of the evaluator.
@@ -165,6 +162,7 @@ first will be printed into the backtrace buffer."
165 (if (get-buffer "*Backtrace*") 162 (if (get-buffer "*Backtrace*")
166 (with-current-buffer (get-buffer "*Backtrace*") 163 (with-current-buffer (get-buffer "*Backtrace*")
167 (list major-mode (buffer-string))))) 164 (list major-mode (buffer-string)))))
165 (debugger-args args)
168 (debugger-buffer (get-buffer-create "*Backtrace*")) 166 (debugger-buffer (get-buffer-create "*Backtrace*"))
169 (debugger-old-buffer (current-buffer)) 167 (debugger-old-buffer (current-buffer))
170 (debugger-window nil) 168 (debugger-window nil)
@@ -219,7 +217,7 @@ first will be printed into the backtrace buffer."
219 (save-excursion 217 (save-excursion
220 (when (eq (car debugger-args) 'debug) 218 (when (eq (car debugger-args) 'debug)
221 ;; Skip the frames for backtrace-debug, byte-code, 219 ;; Skip the frames for backtrace-debug, byte-code,
222 ;; and implement-debug-on-entry. 220 ;; debug--implement-debug-on-entry and the advice's `apply'.
223 (backtrace-debug 4 t) 221 (backtrace-debug 4 t)
224 ;; Place an extra debug-on-exit for macro's. 222 ;; Place an extra debug-on-exit for macro's.
225 (when (eq 'lambda (car-safe (cadr (backtrace-frame 4)))) 223 (when (eq 'lambda (car-safe (cadr (backtrace-frame 4))))
@@ -318,7 +316,7 @@ first will be printed into the backtrace buffer."
318 (setq debug-on-next-call debugger-step-after-exit) 316 (setq debug-on-next-call debugger-step-after-exit)
319 debugger-value))) 317 debugger-value)))
320 318
321(defun debugger-setup-buffer (debugger-args) 319(defun debugger-setup-buffer (args)
322 "Initialize the `*Backtrace*' buffer for entry to the debugger. 320 "Initialize the `*Backtrace*' buffer for entry to the debugger.
323That buffer should be current already." 321That buffer should be current already."
324 (setq buffer-read-only nil) 322 (setq buffer-read-only nil)
@@ -334,20 +332,22 @@ That buffer should be current already."
334 (delete-region (point) 332 (delete-region (point)
335 (progn 333 (progn
336 (search-forward "\n debug(") 334 (search-forward "\n debug(")
337 (forward-line (if (eq (car debugger-args) 'debug) 335 (forward-line (if (eq (car args) 'debug)
338 2 ; Remove implement-debug-on-entry frame. 336 ;; Remove debug--implement-debug-on-entry
337 ;; and the advice's `apply' frame.
338 3
339 1)) 339 1))
340 (point))) 340 (point)))
341 (insert "Debugger entered") 341 (insert "Debugger entered")
342 ;; lambda is for debug-on-call when a function call is next. 342 ;; lambda is for debug-on-call when a function call is next.
343 ;; debug is for debug-on-entry function called. 343 ;; debug is for debug-on-entry function called.
344 (pcase (car debugger-args) 344 (pcase (car args)
345 ((or `lambda `debug) 345 ((or `lambda `debug)
346 (insert "--entering a function:\n")) 346 (insert "--entering a function:\n"))
347 ;; Exiting a function. 347 ;; Exiting a function.
348 (`exit 348 (`exit
349 (insert "--returning value: ") 349 (insert "--returning value: ")
350 (setq debugger-value (nth 1 debugger-args)) 350 (setq debugger-value (nth 1 args))
351 (prin1 debugger-value (current-buffer)) 351 (prin1 debugger-value (current-buffer))
352 (insert ?\n) 352 (insert ?\n)
353 (delete-char 1) 353 (delete-char 1)
@@ -356,7 +356,7 @@ That buffer should be current already."
356 ;; Debugger entered for an error. 356 ;; Debugger entered for an error.
357 (`error 357 (`error
358 (insert "--Lisp error: ") 358 (insert "--Lisp error: ")
359 (prin1 (nth 1 debugger-args) (current-buffer)) 359 (prin1 (nth 1 args) (current-buffer))
360 (insert ?\n)) 360 (insert ?\n))
361 ;; debug-on-call, when the next thing is an eval. 361 ;; debug-on-call, when the next thing is an eval.
362 (`t 362 (`t
@@ -364,8 +364,8 @@ That buffer should be current already."
364 ;; User calls debug directly. 364 ;; User calls debug directly.
365 (_ 365 (_
366 (insert ": ") 366 (insert ": ")
367 (prin1 (if (eq (car debugger-args) 'nil) 367 (prin1 (if (eq (car args) 'nil)
368 (cdr debugger-args) debugger-args) 368 (cdr args) args)
369 (current-buffer)) 369 (current-buffer))
370 (insert ?\n))) 370 (insert ?\n)))
371 ;; After any frame that uses eval-buffer, 371 ;; After any frame that uses eval-buffer,
@@ -525,9 +525,10 @@ removes itself from that hook."
525 (count 0)) 525 (count 0))
526 (while (not (eq (cadr (backtrace-frame count)) 'debug)) 526 (while (not (eq (cadr (backtrace-frame count)) 'debug))
527 (setq count (1+ count))) 527 (setq count (1+ count)))
528 ;; Skip implement-debug-on-entry frame. 528 ;; Skip debug--implement-debug-on-entry frame.
529 (when (eq 'implement-debug-on-entry (cadr (backtrace-frame (1+ count)))) 529 (when (eq 'debug--implement-debug-on-entry
530 (setq count (1+ count))) 530 (cadr (backtrace-frame (1+ count))))
531 (setq count (+ 2 count)))
531 (goto-char (point-min)) 532 (goto-char (point-min))
532 (when (looking-at "Debugger entered--\\(Lisp error\\|returning value\\):") 533 (when (looking-at "Debugger entered--\\(Lisp error\\|returning value\\):")
533 (goto-char (match-end 0)) 534 (goto-char (match-end 0))
@@ -694,10 +695,10 @@ Applies to the frame whose line point is on in the backtrace."
694 :help "Continue to exit from this frame, with all debug-on-entry suspended")) 695 :help "Continue to exit from this frame, with all debug-on-entry suspended"))
695 (define-key menu-map [deb-cont] 696 (define-key menu-map [deb-cont]
696 '(menu-item "Continue" debugger-continue 697 '(menu-item "Continue" debugger-continue
697 :help "Continue, evaluating this expression without stopping")) 698 :help "Continue, evaluating this expression without stopping"))
698 (define-key menu-map [deb-step] 699 (define-key menu-map [deb-step]
699 '(menu-item "Step through" debugger-step-through 700 '(menu-item "Step through" debugger-step-through
700 :help "Proceed, stepping through subexpressions of this expression")) 701 :help "Proceed, stepping through subexpressions of this expression"))
701 map)) 702 map))
702 703
703(put 'debugger-mode 'mode-class 'special) 704(put 'debugger-mode 'mode-class 'special)
@@ -777,7 +778,7 @@ For the cross-reference format, see `help-make-xrefs'."
777 778
778;; When you change this, you may also need to change the number of 779;; When you change this, you may also need to change the number of
779;; frames that the debugger skips. 780;; frames that the debugger skips.
780(defun implement-debug-on-entry () 781(defun debug--implement-debug-on-entry (&rest _ignore)
781 "Conditionally call the debugger. 782 "Conditionally call the debugger.
782A call to this function is inserted by `debug-on-entry' to cause 783A call to this function is inserted by `debug-on-entry' to cause
783functions to break on entry." 784functions to break on entry."
@@ -785,12 +786,6 @@ functions to break on entry."
785 nil 786 nil
786 (funcall debugger 'debug))) 787 (funcall debugger 'debug)))
787 788
788(defun debugger-special-form-p (symbol)
789 "Return whether SYMBOL is a special form."
790 (and (fboundp symbol)
791 (subrp (symbol-function symbol))
792 (eq (cdr (subr-arity (symbol-function symbol))) 'unevalled)))
793
794;;;###autoload 789;;;###autoload
795(defun debug-on-entry (function) 790(defun debug-on-entry (function)
796 "Request FUNCTION to invoke debugger each time it is called. 791 "Request FUNCTION to invoke debugger each time it is called.
@@ -808,7 +803,7 @@ Use \\[cancel-debug-on-entry] to cancel the effect of this command.
808Redefining FUNCTION also cancels it." 803Redefining FUNCTION also cancels it."
809 (interactive 804 (interactive
810 (let ((fn (function-called-at-point)) val) 805 (let ((fn (function-called-at-point)) val)
811 (when (debugger-special-form-p fn) 806 (when (special-form-p fn)
812 (setq fn nil)) 807 (setq fn nil))
813 (setq val (completing-read 808 (setq val (completing-read
814 (if fn 809 (if fn
@@ -817,36 +812,21 @@ Redefining FUNCTION also cancels it."
817 obarray 812 obarray
818 #'(lambda (symbol) 813 #'(lambda (symbol)
819 (and (fboundp symbol) 814 (and (fboundp symbol)
820 (not (debugger-special-form-p symbol)))) 815 (not (special-form-p symbol))))
821 t nil nil (symbol-name fn))) 816 t nil nil (symbol-name fn)))
822 (list (if (equal val "") fn (intern val))))) 817 (list (if (equal val "") fn (intern val)))))
823 ;; FIXME: Use advice.el. 818 (advice-add function :before #'debug--implement-debug-on-entry)
824 (when (debugger-special-form-p function)
825 (error "Function %s is a special form" function))
826 (if (or (symbolp (symbol-function function))
827 (subrp (symbol-function function)))
828 ;; The function is built-in or aliased to another function.
829 ;; Create a wrapper in which we can add the debug call.
830 (fset function `(lambda (&rest debug-on-entry-args)
831 ,(interactive-form (symbol-function function))
832 (apply ',(symbol-function function)
833 debug-on-entry-args)))
834 (when (autoloadp (symbol-function function))
835 ;; The function is autoloaded. Load its real definition.
836 (autoload-do-load (symbol-function function) function))
837 (when (or (not (consp (symbol-function function)))
838 (and (eq (car (symbol-function function)) 'macro)
839 (not (consp (cdr (symbol-function function))))))
840 ;; The function is byte-compiled. Create a wrapper in which
841 ;; we can add the debug call.
842 (debug-convert-byte-code function)))
843 (unless (consp (symbol-function function))
844 (error "Definition of %s is not a list" function))
845 (fset function (debug-on-entry-1 function t))
846 (unless (memq function debug-function-list)
847 (push function debug-function-list))
848 function) 819 function)
849 820
821(defun debug--function-list ()
822 "List of functions currently set for debug on entry."
823 (let ((funs '()))
824 (mapatoms
825 (lambda (s)
826 (when (advice-member-p #'debug--implement-debug-on-entry s)
827 (push s funs))))
828 funs))
829
850;;;###autoload 830;;;###autoload
851(defun cancel-debug-on-entry (&optional function) 831(defun cancel-debug-on-entry (&optional function)
852 "Undo effect of \\[debug-on-entry] on FUNCTION. 832 "Undo effect of \\[debug-on-entry] on FUNCTION.
@@ -857,80 +837,16 @@ To specify a nil argument interactively, exit with an empty minibuffer."
857 (list (let ((name 837 (list (let ((name
858 (completing-read 838 (completing-read
859 "Cancel debug on entry to function (default all functions): " 839 "Cancel debug on entry to function (default all functions): "
860 (mapcar 'symbol-name debug-function-list) nil t))) 840 (mapcar #'symbol-name (debug--function-list)) nil t)))
861 (when name 841 (when name
862 (unless (string= name "") 842 (unless (string= name "")
863 (intern name)))))) 843 (intern name))))))
864 (if (and function 844 (if function
865 (not (string= function ""))) ; Pre 22.1 compatibility test.
866 (progn 845 (progn
867 (let ((defn (debug-on-entry-1 function nil))) 846 (advice-remove function #'debug--implement-debug-on-entry)
868 (condition-case nil
869 (when (and (equal (nth 1 defn) '(&rest debug-on-entry-args))
870 (eq (car (nth 3 defn)) 'apply))
871 ;; `defn' is a wrapper introduced in debug-on-entry.
872 ;; Get rid of it since we don't need it any more.
873 (setq defn (nth 1 (nth 1 (nth 3 defn)))))
874 (error nil))
875 (fset function defn))
876 (setq debug-function-list (delq function debug-function-list))
877 function) 847 function)
878 (message "Cancelling debug-on-entry for all functions") 848 (message "Cancelling debug-on-entry for all functions")
879 (mapcar 'cancel-debug-on-entry debug-function-list))) 849 (mapcar #'cancel-debug-on-entry (debug--function-list))))
880
881(defun debug-arglist (definition)
882 ;; FIXME: copied from ad-arglist.
883 "Return the argument list of DEFINITION."
884 (require 'help-fns)
885 (help-function-arglist definition 'preserve-names))
886
887(defun debug-convert-byte-code (function)
888 (let* ((defn (symbol-function function))
889 (macro (eq (car-safe defn) 'macro)))
890 (when macro (setq defn (cdr defn)))
891 (when (byte-code-function-p defn)
892 (let* ((args (debug-arglist defn))
893 (body
894 `((,(if (memq '&rest args) #'apply #'funcall)
895 ,defn
896 ,@(remq '&rest (remq '&optional args))))))
897 (if (> (length defn) 5)
898 ;; The mere presence of field 5 is sufficient to make
899 ;; it interactive.
900 (push `(interactive ,(aref defn 5)) body))
901 (if (and (> (length defn) 4) (aref defn 4))
902 ;; Use `documentation' here, to get the actual string,
903 ;; in case the compiled function has a reference
904 ;; to the .elc file.
905 (setq body (cons (documentation function) body)))
906 (setq defn `(closure (t) ,args ,@body)))
907 (when macro (setq defn (cons 'macro defn)))
908 (fset function defn))))
909
910(defun debug-on-entry-1 (function flag)
911 (let* ((defn (symbol-function function))
912 (tail defn))
913 (when (eq (car-safe tail) 'macro)
914 (setq tail (cdr tail)))
915 (if (not (memq (car-safe tail) '(closure lambda)))
916 ;; Only signal an error when we try to set debug-on-entry.
917 ;; When we try to clear debug-on-entry, we are now done.
918 (when flag
919 (error "%s is not a user-defined Lisp function" function))
920 (if (eq (car tail) 'closure) (setq tail (cdr tail)))
921 (setq tail (cdr tail))
922 ;; Skip the docstring.
923 (when (and (stringp (cadr tail)) (cddr tail))
924 (setq tail (cdr tail)))
925 ;; Skip the interactive form.
926 (when (eq 'interactive (car-safe (cadr tail)))
927 (setq tail (cdr tail)))
928 (unless (eq flag (equal (cadr tail) '(implement-debug-on-entry)))
929 ;; Add/remove debug statement as needed.
930 (setcdr tail (if flag
931 (cons '(implement-debug-on-entry) (cdr tail))
932 (cddr tail)))))
933 defn))
934 850
935(defun debugger-list-functions () 851(defun debugger-list-functions ()
936 "Display a list of all the functions now set to debug on entry." 852 "Display a list of all the functions now set to debug on entry."
@@ -940,17 +856,18 @@ To specify a nil argument interactively, exit with an empty minibuffer."
940 (called-interactively-p 'interactive)) 856 (called-interactively-p 'interactive))
941 (with-output-to-temp-buffer (help-buffer) 857 (with-output-to-temp-buffer (help-buffer)
942 (with-current-buffer standard-output 858 (with-current-buffer standard-output
943 (if (null debug-function-list) 859 (let ((funs (debug--function-list)))
944 (princ "No debug-on-entry functions now\n") 860 (if (null funs)
945 (princ "Functions set to debug on entry:\n\n") 861 (princ "No debug-on-entry functions now\n")
946 (dolist (fun debug-function-list) 862 (princ "Functions set to debug on entry:\n\n")
947 (make-text-button (point) (progn (prin1 fun) (point)) 863 (dolist (fun funs)
948 'type 'help-function 864 (make-text-button (point) (progn (prin1 fun) (point))
949 'help-args (list fun)) 865 'type 'help-function
950 (terpri)) 866 'help-args (list fun))
951 (terpri) 867 (terpri))
952 (princ "Note: if you have redefined a function, then it may no longer\n") 868 (terpri)
953 (princ "be set to debug on entry, even if it is in the list."))))) 869 (princ "Note: if you have redefined a function, then it may no longer\n")
870 (princ "be set to debug on entry, even if it is in the list."))))))
954 871
955(provide 'debug) 872(provide 'debug)
956 873
diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el
index b94817cdb02..067b45f5cd8 100644
--- a/lisp/emacs-lisp/elp.el
+++ b/lisp/emacs-lisp/elp.el
@@ -1,4 +1,4 @@
1;;; elp.el --- Emacs Lisp Profiler 1;;; elp.el --- Emacs Lisp Profiler -*- lexical-binding: t -*-
2 2
3;; Copyright (C) 1994-1995, 1997-1998, 2001-2012 3;; Copyright (C) 1994-1995, 1997-1998, 2001-2012
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
@@ -124,6 +124,7 @@
124 124
125;;; Code: 125;;; Code:
126 126
127(eval-when-compile (require 'cl-lib))
127 128
128;; start of user configuration variables 129;; start of user configuration variables
129;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 130;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
@@ -148,9 +149,9 @@ Results are displayed with the `elp-results' command."
148 "Non-nil specifies ELP results sorting function. 149 "Non-nil specifies ELP results sorting function.
149These functions are currently available: 150These functions are currently available:
150 151
151 elp-sort-by-call-count -- sort by the highest call count 152 `elp-sort-by-call-count' -- sort by the highest call count
152 elp-sort-by-total-time -- sort by the highest total time 153 `elp-sort-by-total-time' -- sort by the highest total time
153 elp-sort-by-average-time -- sort by the highest average times 154 `elp-sort-by-average-time' -- sort by the highest average times
154 155
155You can write your own sort function. It should adhere to the 156You can write your own sort function. It should adhere to the
156interface specified by the PREDICATE argument for `sort'. 157interface specified by the PREDICATE argument for `sort'.
@@ -167,7 +168,7 @@ If a number, no function that has been called fewer than that number
167of times will be displayed in the output buffer. If nil, all 168of times will be displayed in the output buffer. If nil, all
168functions will be displayed." 169functions will be displayed."
169 :type '(choice integer 170 :type '(choice integer
170 (const :tag "Show All" nil)) 171 (const :tag "Show All" nil))
171 :group 'elp) 172 :group 'elp)
172 173
173(defcustom elp-use-standard-output nil 174(defcustom elp-use-standard-output nil
@@ -193,9 +194,6 @@ In other words, a new unique buffer is create every time you run
193(defconst elp-timer-info-property 'elp-info 194(defconst elp-timer-info-property 'elp-info
194 "ELP information property name.") 195 "ELP information property name.")
195 196
196(defvar elp-all-instrumented-list nil
197 "List of all functions currently being instrumented.")
198
199(defvar elp-record-p t 197(defvar elp-record-p t
200 "Controls whether functions should record times or not. 198 "Controls whether functions should record times or not.
201This variable is set by the master function.") 199This variable is set by the master function.")
@@ -205,7 +203,7 @@ This variable is set by the master function.")
205 203
206(defvar elp-not-profilable 204(defvar elp-not-profilable
207 ;; First, the functions used inside each instrumented function: 205 ;; First, the functions used inside each instrumented function:
208 '(elp-wrapper called-interactively-p 206 '(called-interactively-p
209 ;; Then the functions used by the above functions. I used 207 ;; Then the functions used by the above functions. I used
210 ;; (delq nil (mapcar (lambda (x) (and (symbolp x) (fboundp x) x)) 208 ;; (delq nil (mapcar (lambda (x) (and (symbolp x) (fboundp x) x))
211 ;; (aref (symbol-function 'elp-wrapper) 2))) 209 ;; (aref (symbol-function 'elp-wrapper) 2)))
@@ -223,60 +221,21 @@ them would thus lead to infinite recursion.")
223 (fboundp fun) 221 (fboundp fun)
224 (not (or (memq fun elp-not-profilable) 222 (not (or (memq fun elp-not-profilable)
225 (keymapp fun) 223 (keymapp fun)
226 (memq (car-safe (symbol-function fun)) '(autoload macro)) 224 (autoloadp (symbol-function fun)) ;FIXME: Why not just load it?
227 (condition-case nil 225 (special-form-p fun)))))
228 (when (subrp (indirect-function fun))
229 (eq 'unevalled
230 (cdr (subr-arity (indirect-function fun)))))
231 (error nil))))))
232 226
227(defconst elp--advice-name 'ELP-instrumentation\ )
233 228
234;;;###autoload 229;;;###autoload
235(defun elp-instrument-function (funsym) 230(defun elp-instrument-function (funsym)
236 "Instrument FUNSYM for profiling. 231 "Instrument FUNSYM for profiling.
237FUNSYM must be a symbol of a defined function." 232FUNSYM must be a symbol of a defined function."
238 (interactive "aFunction to instrument: ") 233 (interactive "aFunction to instrument: ")
239 ;; restore the function. this is necessary to avoid infinite 234 (let* ((infovec (vector 0 0)))
240 ;; recursion of already instrumented functions (i.e. elp-wrapper
241 ;; calling elp-wrapper ad infinitum). it is better to simply
242 ;; restore the function than to throw an error. this will work
243 ;; properly in the face of eval-defun because if the function was
244 ;; redefined, only the timer info will be nil'd out since
245 ;; elp-restore-function is smart enough not to trash the new
246 ;; definition.
247 (elp-restore-function funsym)
248 (let* ((funguts (symbol-function funsym))
249 (infovec (vector 0 0 funguts))
250 (newguts '(lambda (&rest args))))
251 ;; we cannot profile macros
252 (and (eq (car-safe funguts) 'macro)
253 (error "ELP cannot profile macro: %s" funsym))
254 ;; TBD: at some point it might be better to load the autoloaded
255 ;; function instead of throwing an error. if we do this, then we
256 ;; probably want elp-instrument-package to be updated with the
257 ;; newly loaded list of functions. i'm not sure it's smart to do
258 ;; the autoload here, since that could have side effects, and
259 ;; elp-instrument-function is similar (in my mind) to defun-ish
260 ;; type functionality (i.e. it shouldn't execute the function).
261 (and (autoloadp funguts)
262 (error "ELP cannot profile autoloaded function: %s" funsym))
263 ;; We cannot profile functions used internally during profiling. 235 ;; We cannot profile functions used internally during profiling.
264 (unless (elp-profilable-p funsym) 236 (unless (elp-profilable-p funsym)
265 (error "ELP cannot profile the function: %s" funsym)) 237 (error "ELP cannot profile the function: %s" funsym))
266 ;; put rest of newguts together 238 ;; The info vector data structure is a 2 element vector. The 0th
267 (if (commandp funsym)
268 (setq newguts (append newguts '((interactive)))))
269 (setq newguts (append newguts `((elp-wrapper
270 (quote ,funsym)
271 ,(when (commandp funsym)
272 '(called-interactively-p 'any))
273 args))))
274 ;; to record profiling times, we set the symbol's function
275 ;; definition so that it runs the elp-wrapper function with the
276 ;; function symbol as an argument. We place the old function
277 ;; definition on the info vector.
278 ;;
279 ;; The info vector data structure is a 3 element vector. The 0th
280 ;; element is the call-count, i.e. the total number of times this 239 ;; element is the call-count, i.e. the total number of times this
281 ;; function has been entered. This value is bumped up on entry to 240 ;; function has been entered. This value is bumped up on entry to
282 ;; the function so that non-local exists are still recorded. TBD: 241 ;; the function so that non-local exists are still recorded. TBD:
@@ -285,72 +244,45 @@ FUNSYM must be a symbol of a defined function."
285 ;; The 1st element is the total amount of time in seconds that has 244 ;; The 1st element is the total amount of time in seconds that has
286 ;; been spent inside this function. This number is added to on 245 ;; been spent inside this function. This number is added to on
287 ;; function exit. 246 ;; function exit.
288 ;;
289 ;; The 2nd element is the old function definition list. This gets
290 ;; funcall'd in between start/end time retrievals. I believe that
291 ;; this lets us profile even byte-compiled functions.
292 247
293 ;; put the info vector on the property list 248 ;; Put the info vector on the property list.
294 (put funsym elp-timer-info-property infovec) 249 (put funsym elp-timer-info-property infovec)
295 250
296 ;; Set the symbol's new profiling function definition to run 251 ;; Set the symbol's new profiling function definition to run
297 ;; elp-wrapper. 252 ;; ELP wrapper.
298 (let ((advice-info (get funsym 'ad-advice-info))) 253 (advice-add funsym :around (elp--make-wrapper funsym)
299 (if advice-info 254 `((name . ,elp--advice-name)))))
300 (progn 255
301 ;; If function is advised, don't let Advice change 256(defun elp--instrumented-p (sym)
302 ;; its definition from under us during the `fset'. 257 (advice-member-p elp--advice-name sym))
303 (put funsym 'ad-advice-info nil)
304 (fset funsym newguts)
305 (put funsym 'ad-advice-info advice-info))
306 (fset funsym newguts)))
307
308 ;; add this function to the instrumentation list
309 (unless (memq funsym elp-all-instrumented-list)
310 (push funsym elp-all-instrumented-list))))
311 258
312(defun elp-restore-function (funsym) 259(defun elp-restore-function (funsym)
313 "Restore an instrumented function to its original definition. 260 "Restore an instrumented function to its original definition.
314Argument FUNSYM is the symbol of a defined function." 261Argument FUNSYM is the symbol of a defined function."
315 (interactive "aFunction to restore: ") 262 (interactive
316 (let ((info (get funsym elp-timer-info-property))) 263 (list
317 ;; delete the function from the all instrumented list 264 (intern
318 (setq elp-all-instrumented-list 265 (completing-read "Function to restore: " obarray
319 (delq funsym elp-all-instrumented-list)) 266 #'elp--instrumented-p t))))
320 267 ;; If the function was the master, reset the master.
321 ;; if the function was the master, reset the master 268 (if (eq funsym elp-master)
322 (if (eq funsym elp-master) 269 (setq elp-master nil
323 (setq elp-master nil 270 elp-record-p t))
324 elp-record-p t)) 271
325 272 ;; Zap the properties.
326 ;; zap the properties 273 (put funsym elp-timer-info-property nil)
327 (put funsym elp-timer-info-property nil) 274
328 275 (advice-remove funsym elp--advice-name))
329 ;; restore the original function definition, but if the function
330 ;; wasn't instrumented do nothing. we do this after the above
331 ;; because its possible the function got un-instrumented due to
332 ;; circumstances beyond our control. Also, check to make sure
333 ;; that the current function symbol points to elp-wrapper. If
334 ;; not, then the user probably did an eval-defun, or loaded a
335 ;; byte-compiled version, while the function was instrumented and
336 ;; we don't want to destroy the new definition. can it ever be
337 ;; the case that a lisp function can be compiled instrumented?
338 (and info
339 (functionp funsym)
340 (not (byte-code-function-p (symbol-function funsym)))
341 (assq 'elp-wrapper (symbol-function funsym))
342 (fset funsym (aref info 2)))))
343 276
344;;;###autoload 277;;;###autoload
345(defun elp-instrument-list (&optional list) 278(defun elp-instrument-list (&optional list)
346 "Instrument, for profiling, all functions in `elp-function-list'. 279 "Instrument, for profiling, all functions in `elp-function-list'.
347Use optional LIST if provided instead. 280Use optional LIST if provided instead.
348If called interactively, read LIST using the minibuffer." 281If called interactively, read LIST using the minibuffer."
349 (interactive "PList of functions to instrument: ") 282 (interactive "PList of functions to instrument: ") ;FIXME: Doesn't work?!
350 (unless (listp list) 283 (unless (listp list)
351 (signal 'wrong-type-argument (list 'listp list))) 284 (signal 'wrong-type-argument (list 'listp list)))
352 (let ((list (or list elp-function-list))) 285 (mapcar #'elp-instrument-function (or list elp-function-list)))
353 (mapcar 'elp-instrument-function list)))
354 286
355;;;###autoload 287;;;###autoload
356(defun elp-instrument-package (prefix) 288(defun elp-instrument-package (prefix)
@@ -371,15 +303,13 @@ For example, to instrument all ELP functions, do the following:
371(defun elp-restore-list (&optional list) 303(defun elp-restore-list (&optional list)
372 "Restore the original definitions for all functions in `elp-function-list'. 304 "Restore the original definitions for all functions in `elp-function-list'.
373Use optional LIST if provided instead." 305Use optional LIST if provided instead."
374 (interactive "PList of functions to restore: ") 306 (interactive "PList of functions to restore: ") ;FIXME: Doesn't work!?
375 (let ((list (or list elp-function-list))) 307 (mapcar #'elp-restore-function (or list elp-function-list)))
376 (mapcar 'elp-restore-function list)))
377 308
378(defun elp-restore-all () 309(defun elp-restore-all ()
379 "Restore the original definitions of all functions being profiled." 310 "Restore the original definitions of all functions being profiled."
380 (interactive) 311 (interactive)
381 (elp-restore-list elp-all-instrumented-list)) 312 (mapatoms #'elp-restore-function))
382
383 313
384(defun elp-reset-function (funsym) 314(defun elp-reset-function (funsym)
385 "Reset the profiling information for FUNSYM." 315 "Reset the profiling information for FUNSYM."
@@ -395,30 +325,36 @@ Use optional LIST if provided instead."
395(defun elp-reset-list (&optional list) 325(defun elp-reset-list (&optional list)
396 "Reset the profiling information for all functions in `elp-function-list'. 326 "Reset the profiling information for all functions in `elp-function-list'.
397Use optional LIST if provided instead." 327Use optional LIST if provided instead."
398 (interactive "PList of functions to reset: ") 328 (interactive "PList of functions to reset: ") ;FIXME: Doesn't work!?
399 (let ((list (or list elp-function-list))) 329 (let ((list (or list elp-function-list)))
400 (mapcar 'elp-reset-function list))) 330 (mapcar 'elp-reset-function list)))
401 331
402(defun elp-reset-all () 332(defun elp-reset-all ()
403 "Reset the profiling information for all functions being profiled." 333 "Reset the profiling information for all functions being profiled."
404 (interactive) 334 (interactive)
405 (elp-reset-list elp-all-instrumented-list)) 335 (mapatoms (lambda (sym)
336 (if (get sym elp-timer-info-property)
337 (elp-reset-function sym)))))
406 338
407(defun elp-set-master (funsym) 339(defun elp-set-master (funsym)
408 "Set the master function for profiling." 340 "Set the master function for profiling."
409 (interactive "aMaster function: ") 341 (interactive
410 ;; when there's a master function, recording is turned off by 342 (list
411 ;; default 343 (intern
344 (completing-read "Master function: " obarray
345 #'elp--instrumented-p
346 t nil nil (if elp-master (symbol-name elp-master))))))
347 ;; When there's a master function, recording is turned off by default.
412 (setq elp-master funsym 348 (setq elp-master funsym
413 elp-record-p nil) 349 elp-record-p nil)
414 ;; make sure master function is instrumented 350 ;; Make sure master function is instrumented.
415 (or (memq funsym elp-all-instrumented-list) 351 (or (elp--instrumented-p funsym)
416 (elp-instrument-function funsym))) 352 (elp-instrument-function funsym)))
417 353
418(defun elp-unset-master () 354(defun elp-unset-master ()
419 "Unset the master function." 355 "Unset the master function."
420 (interactive) 356 (interactive)
421 ;; when there's no master function, recording is turned on by default. 357 ;; When there's no master function, recording is turned on by default.
422 (setq elp-master nil 358 (setq elp-master nil
423 elp-record-p t)) 359 elp-record-p t))
424 360
@@ -426,49 +362,40 @@ Use optional LIST if provided instead."
426(defsubst elp-elapsed-time (start end) 362(defsubst elp-elapsed-time (start end)
427 (float-time (time-subtract end start))) 363 (float-time (time-subtract end start)))
428 364
429(defun elp-wrapper (funsym interactive-p args) 365(defun elp--make-wrapper (funsym)
430 "This function has been instrumented for profiling by the ELP. 366 "Make the piece of advice that instruments FUNSYM."
367 (lambda (func &rest args)
368 "This function has been instrumented for profiling by the ELP.
431ELP is the Emacs Lisp Profiler. To restore the function to its 369ELP is the Emacs Lisp Profiler. To restore the function to its
432original definition, use \\[elp-restore-function] or \\[elp-restore-all]." 370original definition, use \\[elp-restore-function] or \\[elp-restore-all]."
433 ;; turn on recording if this is the master function 371 ;; turn on recording if this is the master function
434 (if (and elp-master 372 (if (and elp-master
435 (eq funsym elp-master)) 373 (eq funsym elp-master))
436 (setq elp-record-p t)) 374 (setq elp-record-p t))
437 ;; get info vector and original function symbol 375 ;; get info vector and original function symbol
438 (let* ((info (get funsym elp-timer-info-property)) 376 (let* ((info (get funsym elp-timer-info-property))
439 (func (aref info 2)) 377 result)
440 result) 378 (or func
441 (or func 379 (error "%s is not instrumented for profiling" funsym))
442 (error "%s is not instrumented for profiling" funsym)) 380 (if (not elp-record-p)
443 (if (not elp-record-p) 381 ;; when not recording, just call the original function symbol
444 ;; when not recording, just call the original function symbol 382 ;; and return the results.
445 ;; and return the results. 383 (setq result (apply func args))
446 (setq result 384 ;; we are recording times
447 (if interactive-p 385 (let (enter-time exit-time)
448 (call-interactively func) 386 ;; increment the call-counter
449 (apply func args))) 387 (cl-incf (aref info 0))
450 ;; we are recording times
451 (let (enter-time exit-time)
452 ;; increment the call-counter
453 (aset info 0 (1+ (aref info 0)))
454 ;; now call the old symbol function, checking to see if it
455 ;; should be called interactively. make sure we return the
456 ;; correct value
457 (if interactive-p
458 (setq enter-time (current-time)
459 result (call-interactively func)
460 exit-time (current-time))
461 (setq enter-time (current-time) 388 (setq enter-time (current-time)
462 result (apply func args) 389 result (apply func args)
463 exit-time (current-time))) 390 exit-time (current-time))
464 ;; calculate total time in function 391 ;; calculate total time in function
465 (aset info 1 (+ (aref info 1) (elp-elapsed-time enter-time exit-time))) 392 (cl-incf (aref info 1) (elp-elapsed-time enter-time exit-time))
466 )) 393 ))
467 ;; turn off recording if this is the master function 394 ;; turn off recording if this is the master function
468 (if (and elp-master 395 (if (and elp-master
469 (eq funsym elp-master)) 396 (eq funsym elp-master))
470 (setq elp-record-p nil)) 397 (setq elp-record-p nil))
471 result)) 398 result)))
472 399
473 400
474;; shut the byte-compiler up 401;; shut the byte-compiler up
@@ -582,57 +509,58 @@ displayed."
582 (elp-et-len (length et-header)) 509 (elp-et-len (length et-header))
583 (at-header "Average Time") 510 (at-header "Average Time")
584 (elp-at-len (length at-header)) 511 (elp-at-len (length at-header))
585 (resvec 512 (resvec '())
586 (mapcar
587 (function
588 (lambda (funsym)
589 (let* ((info (get funsym elp-timer-info-property))
590 (symname (format "%s" funsym))
591 (cc (aref info 0))
592 (tt (aref info 1)))
593 (if (not info)
594 (insert "No profiling information found for: "
595 symname)
596 (setq longest (max longest (length symname)))
597 (vector cc tt (if (zerop cc)
598 0.0 ;avoid arithmetic div-by-zero errors
599 (/ (float tt) (float cc)))
600 symname)))))
601 elp-all-instrumented-list))
602 ) ; end let* 513 ) ; end let*
514 (mapatoms
515 (lambda (funsym)
516 (when (elp--instrumented-p funsym)
517 (let* ((info (get funsym elp-timer-info-property))
518 (symname (format "%s" funsym))
519 (cc (aref info 0))
520 (tt (aref info 1)))
521 (if (not info)
522 (insert "No profiling information found for: "
523 symname)
524 (setq longest (max longest (length symname)))
525 (push
526 (vector cc tt (if (zerop cc)
527 0.0 ;avoid arithmetic div-by-zero errors
528 (/ (float tt) (float cc)))
529 symname)
530 resvec))))))
603 ;; If printing to stdout, insert the header so it will print. 531 ;; If printing to stdout, insert the header so it will print.
604 ;; Otherwise use header-line-format. 532 ;; Otherwise use header-line-format.
605 (setq elp-field-len (max titlelen longest)) 533 (setq elp-field-len (max titlelen longest))
606 (if (or elp-use-standard-output noninteractive) 534 (if (or elp-use-standard-output noninteractive)
607 (progn 535 (progn
608 (insert title) 536 (insert title)
609 (if (> longest titlelen) 537 (if (> longest titlelen)
610 (progn 538 (progn
611 (insert-char 32 (- longest titlelen)))) 539 (insert-char 32 (- longest titlelen))))
612 (insert " " cc-header " " et-header " " at-header "\n") 540 (insert " " cc-header " " et-header " " at-header "\n")
613 (insert-char ?= elp-field-len) 541 (insert-char ?= elp-field-len)
614 (insert " ") 542 (insert " ")
615 (insert-char ?= elp-cc-len) 543 (insert-char ?= elp-cc-len)
616 (insert " ") 544 (insert " ")
617 (insert-char ?= elp-et-len) 545 (insert-char ?= elp-et-len)
618 (insert " ") 546 (insert " ")
619 (insert-char ?= elp-at-len) 547 (insert-char ?= elp-at-len)
620 (insert "\n")) 548 (insert "\n"))
621 (let ((column 0)) 549 (let ((column 0))
622 (setq header-line-format 550 (setq header-line-format
623 (mapconcat 551 (mapconcat
624 (lambda (title) 552 (lambda (title)
625 (prog1 553 (prog1
626 (concat 554 (concat
627 (propertize " " 555 (propertize " "
628 'display (list 'space :align-to column) 556 'display (list 'space :align-to column)
629 'face 'fixed-pitch) 557 'face 'fixed-pitch)
630 title) 558 title)
631 (setq column (+ column 2 559 (setq column (+ column 2
632 (if (= column 0) 560 (if (= column 0)
633 elp-field-len 561 elp-field-len
634 (length title)))))) 562 (length title))))))
635 (list title cc-header et-header at-header) "")))) 563 (list title cc-header et-header at-header) ""))))
636 ;; if sorting is enabled, then sort the results list. in either 564 ;; if sorting is enabled, then sort the results list. in either
637 ;; case, call elp-output-result to output the result in the 565 ;; case, call elp-output-result to output the result in the
638 ;; buffer 566 ;; buffer
@@ -644,7 +572,7 @@ displayed."
644 (pop-to-buffer resultsbuf) 572 (pop-to-buffer resultsbuf)
645 ;; copy results to standard-output? 573 ;; copy results to standard-output?
646 (if (or elp-use-standard-output noninteractive) 574 (if (or elp-use-standard-output noninteractive)
647 (princ (buffer-substring (point-min) (point-max))) 575 (princ (buffer-substring (point-min) (point-max)))
648 (goto-char (point-min))) 576 (goto-char (point-min)))
649 ;; reset profiling info if desired 577 ;; reset profiling info if desired
650 (and elp-reset-after-results 578 (and elp-reset-after-results
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index d6c91539a90..58bfae5b503 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -111,7 +111,7 @@ DO must return an Elisp expression."
111GETTER will be bound to a copyable expression that returns the value 111GETTER will be bound to a copyable expression that returns the value
112of PLACE. 112of PLACE.
113SETTER will be bound to a function that takes an expression V and returns 113SETTER will be bound to a function that takes an expression V and returns
114and new expression that sets PLACE to V. 114a new expression that sets PLACE to V.
115BODY should return some Elisp expression E manipulating PLACE via GETTER 115BODY should return some Elisp expression E manipulating PLACE via GETTER
116and SETTER. 116and SETTER.
117The returned value will then be an Elisp expression that first evaluates 117The returned value will then be an Elisp expression that first evaluates
@@ -194,7 +194,7 @@ well for simple place forms.
194Assignments of VAL to (NAME ARGS...) are expanded by binding the argument 194Assignments of VAL to (NAME ARGS...) are expanded by binding the argument
195forms (VAL ARGS...) according to ARGLIST, then executing BODY, which must 195forms (VAL ARGS...) according to ARGLIST, then executing BODY, which must
196return a Lisp form that does the assignment. 196return a Lisp form that does the assignment.
197The first arg in ARLIST (the one that receives VAL) receives an expression 197The first arg in ARGLIST (the one that receives VAL) receives an expression
198which can do arbitrary things, whereas the other arguments are all guaranteed 198which can do arbitrary things, whereas the other arguments are all guaranteed
199to be pure and copyable. Example use: 199to be pure and copyable. Example use:
200 (gv-define-setter aref (v a i) `(aset ,a ,i ,v))" 200 (gv-define-setter aref (v a i) `(aset ,a ,i ,v))"
@@ -209,13 +209,20 @@ to be pure and copyable. Example use:
209This macro is an easy-to-use substitute for `gv-define-expander' that works 209This macro is an easy-to-use substitute for `gv-define-expander' that works
210well for simple place forms. Assignments of VAL to (NAME ARGS...) are 210well for simple place forms. Assignments of VAL to (NAME ARGS...) are
211turned into calls of the form (SETTER ARGS... VAL). 211turned into calls of the form (SETTER ARGS... VAL).
212
212If FIX-RETURN is non-nil, then SETTER is not assumed to return VAL and 213If FIX-RETURN is non-nil, then SETTER is not assumed to return VAL and
213instead the assignment is turned into (prog1 VAL (SETTER ARGS... VAL)) 214instead the assignment is turned into something equivalent to
215 \(let ((temp VAL))
216 (SETTER ARGS... temp)
217 temp)
214so as to preserve the semantics of `setf'." 218so as to preserve the semantics of `setf'."
215 (declare (debug (sexp (&or symbolp lambda-expr) &optional sexp))) 219 (declare (debug (sexp (&or symbolp lambda-expr) &optional sexp)))
216 (let ((set-call `(cons ',setter (append args (list val)))))
217 `(gv-define-setter ,name (val &rest args) 220 `(gv-define-setter ,name (val &rest args)
218 ,(if fix-return `(list 'prog1 val ,set-call) set-call)))) 221 ,(if fix-return
222 `(macroexp-let2 nil v val
223 (cons ',setter (append args (list v)))
224 v)
225 `(cons ',setter (append args (list val))))))
219 226
220;;; Typical operations on generalized variables. 227;;; Typical operations on generalized variables.
221 228
@@ -433,6 +440,26 @@ The return value is the last VAL in the list.
433 `(logior (logand ,v ,mask) 440 `(logior (logand ,v ,mask)
434 (logand ,getter (lognot ,mask)))))))))) 441 (logand ,getter (lognot ,mask))))))))))
435 442
443;;; References
444
445;;;###autoload
446(defmacro gv-ref (place)
447 "Return a reference to PLACE.
448This is like the `&' operator of the C language."
449 (gv-letplace (getter setter) place
450 `(cons (lambda () ,getter)
451 (lambda (gv--val) ,(funcall setter 'gv--val)))))
452
453(defsubst gv-deref (ref)
454 "Dereference REF, returning the referenced value.
455This is like the `*' operator of the C language.
456REF must have been previously obtained with `gv-ref'."
457 (funcall (car ref)))
458;; Don't use `declare' because it seems to introduce circularity problems:
459;; Warning: Eager macro-expansion skipped due to cycle:
460;; … => (load "gv.el") => (macroexpand-all (defsubst gv-deref …)) => (macroexpand (defun …)) => (load "gv.el")
461(gv-define-setter gv-deref (v ref) `(funcall (cdr ,ref) ,v))
462
436;;; Vaguely related definitions that should be moved elsewhere. 463;;; Vaguely related definitions that should be moved elsewhere.
437 464
438;; (defun alist-get (key alist) 465;; (defun alist-get (key alist)
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
new file mode 100644
index 00000000000..020a2f89bdb
--- /dev/null
+++ b/lisp/emacs-lisp/nadvice.el
@@ -0,0 +1,348 @@
1;;; nadvice.el --- Light-weight advice primitives for Elisp functions -*- lexical-binding: t -*-
2
3;; Copyright (C) 2012 Free Software Foundation, Inc.
4
5;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6;; Keywords: extensions, lisp, tools
7;; Package: emacs
8
9;; This program is free software; you can redistribute it and/or modify
10;; it under the terms of the GNU General Public License as published by
11;; the Free Software Foundation, either version 3 of the License, or
12;; (at your option) any later version.
13
14;; This program is distributed in the hope that it will be useful,
15;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17;; GNU General Public License for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22;;; Commentary:
23
24;; This package lets you add behavior (which we call "piece of advice") to
25;; existing functions, like the old `advice.el' package, but with much fewer
26;; bells ans whistles. It comes in 2 parts:
27;;
28;; - The first part lets you add/remove functions, similarly to
29;; add/remove-hook, from any "place" (i.e. as accepted by `setf') that
30;; holds a function.
31;; This part provides mainly 2 macros: `add-function' and `remove-function'.
32;;
33;; - The second part provides `add-advice' and `remove-advice' which are
34;; refined version of the previous macros specially tailored for the case
35;; where the place that we want to modify is a `symbol-function'.
36
37;;; Code:
38
39;;;; Lightweight advice/hook
40(defvar advice--where-alist
41 '((:around "\300\301\302\003#\207" 5)
42 (:before "\300\301\002\"\210\300\302\002\"\207" 4)
43 (:after "\300\302\002\"\300\301\003\"\210\207" 5)
44 (:after-until "\300\302\002\"\206\013\000\300\301\002\"\207" 4)
45 (:after-while "\300\302\002\"\205\013\000\300\301\002\"\207" 4)
46 (:before-until "\300\301\002\"\206\013\000\300\302\002\"\207" 4)
47 (:before-while "\300\301\002\"\205\013\000\300\302\002\"\207" 4))
48 "List of descriptions of how to add a function.
49Each element has the form (WHERE BYTECODE STACK) where:
50 WHERE is a keyword indicating where the function is added.
51 BYTECODE is the corresponding byte-code that will be used.
52 STACK is the amount of stack space needed by the byte-code.")
53
54(defvar advice--bytecodes (mapcar #'cadr advice--where-alist))
55
56(defun advice--p (object)
57 (and (byte-code-function-p object)
58 (eq 128 (aref object 0))
59 (memq (length object) '(5 6))
60 (memq (aref object 1) advice--bytecodes)
61 (eq #'apply (aref (aref object 2) 0))))
62
63(defsubst advice--car (f) (aref (aref f 2) 1))
64(defsubst advice--cdr (f) (aref (aref f 2) 2))
65(defsubst advice--props (f) (aref (aref f 2) 3))
66
67(defun advice--make-docstring (_string function)
68 "Build the raw doc-string of SYMBOL, presumably advised."
69 (let ((flist (indirect-function function))
70 (docstring nil))
71 (if (eq 'macro (car-safe flist)) (setq flist (cdr flist)))
72 (while (advice--p flist)
73 (let ((bytecode (aref flist 1))
74 (where nil))
75 (dolist (elem advice--where-alist)
76 (if (eq bytecode (cadr elem)) (setq where (car elem))))
77 (setq docstring
78 (concat
79 docstring
80 (propertize (format "%s advice: " where)
81 'face 'warning)
82 (let ((fun (advice--car flist)))
83 (if (symbolp fun) (format "`%S'" fun)
84 (let* ((name (cdr (assq 'name (advice--props flist))))
85 (doc (documentation fun t))
86 (usage (help-split-fundoc doc function)))
87 (if usage (setq doc (cdr usage)))
88 (if name
89 (if doc
90 (format "%s\n%s" name doc)
91 (format "%s" name))
92 (or doc "No documentation")))))
93 "\n")))
94 (setq flist (advice--cdr flist)))
95 (if docstring (setq docstring (concat docstring "\n")))
96 (let* ((origdoc (unless (eq function flist) ;Avoid inf-loops.
97 (documentation flist t)))
98 (usage (help-split-fundoc origdoc function)))
99 (setq usage (if (null usage)
100 (let ((arglist (help-function-arglist flist)))
101 (format "%S" (help-make-usage function arglist)))
102 (setq origdoc (cdr usage)) (car usage)))
103 (help-add-fundoc-usage (concat docstring origdoc) usage))))
104
105(defvar advice--docstring
106 ;; Can't eval-when-compile nor use defconst because it then gets pure-copied,
107 ;; which drops the text-properties.
108 ;;(eval-when-compile
109 (propertize "Advised function"
110 'dynamic-docstring-function #'advice--make-docstring)) ;; )
111
112(defun advice--make-interactive-form (function main)
113 ;; TODO: Make it possible to do around-like advising on the
114 ;; interactive forms (bug#12844).
115 ;; TODO: make it so that interactive spec can be a constant which
116 ;; dynamically checks the advice--car/cdr to do its job.
117 ;; TODO: Implement interactive-read-args:
118 ;;(when (or (commandp function) (commandp main))
119 ;; `(interactive-read-args
120 ;; (cadr (or (interactive-form function) (interactive-form main)))))
121 ;; FIXME: This loads autoloaded functions too eagerly.
122 (cadr (or (interactive-form function)
123 (interactive-form main))))
124
125(defsubst advice--make-1 (byte-code stack-depth function main props)
126 "Build a function value that adds FUNCTION to MAIN."
127 (let ((adv-sig (gethash main advertised-signature-table))
128 (advice
129 (apply #'make-byte-code 128 byte-code
130 (vector #'apply function main props) stack-depth
131 advice--docstring
132 (when (or (commandp function) (commandp main))
133 (list (advice--make-interactive-form
134 function main))))))
135 (when adv-sig (puthash advice adv-sig advertised-signature-table))
136 advice))
137
138(defun advice--make (where function main props)
139 "Build a function value that adds FUNCTION to MAIN at WHERE.
140WHERE is a symbol to select an entry in `advice--where-alist'."
141 (let ((desc (assq where advice--where-alist)))
142 (unless desc (error "Unknown add-function location `%S'" where))
143 (advice--make-1 (nth 1 desc) (nth 2 desc)
144 function main props)))
145
146(defun advice--member-p (function definition)
147 (let ((found nil))
148 (while (and (not found) (advice--p definition))
149 (if (or (equal function (advice--car definition))
150 (equal function (cdr (assq 'name (advice--props definition)))))
151 (setq found t)
152 (setq definition (advice--cdr definition))))
153 found))
154
155;;;###autoload
156(defun advice--remove-function (flist function)
157 (if (not (advice--p flist))
158 flist
159 (let ((first (advice--car flist))
160 (props (advice--props flist)))
161 (if (or (equal function first)
162 (equal function (cdr (assq 'name props))))
163 (advice--cdr flist)
164 (let* ((rest (advice--cdr flist))
165 (nrest (advice--remove-function rest function)))
166 (if (eq rest nrest) flist
167 (advice--make-1 (aref flist 1) (aref flist 3)
168 first nrest props)))))))
169
170;;;###autoload
171(defmacro add-function (where place function &optional props)
172 ;; TODO:
173 ;; - provide something like `around' for interactive forms.
174 ;; - provide some kind of buffer-local functionality at least when `place'
175 ;; is a variable.
176 ;; - obsolete with-wrapper-hook (mostly requires buffer-local support).
177 ;; - provide some kind of control over ordering. E.g. debug-on-entry, ELP
178 ;; and tracing want to stay first.
179 ;; - maybe also let `where' specify some kind of predicate and use it
180 ;; to implement things like mode-local or eieio-defmethod.
181 ;; :before is like a normal add-hook on a normal hook.
182 ;; :before-while is like add-hook on run-hook-with-args-until-failure.
183 ;; :before-until is like add-hook on run-hook-with-args-until-success.
184 ;; Same with :after-* but for (add-hook ... 'append).
185 "Add a piece of advice on the function stored at PLACE.
186FUNCTION describes the code to add. WHERE describes where to add it.
187WHERE can be explained by showing the resulting new function, as the
188result of combining FUNCTION and the previous value of PLACE, which we
189call OLDFUN here:
190`:before' (lambda (&rest r) (apply FUNCTION r) (apply OLDFUN r))
191`:after' (lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
192`:around' (lambda (&rest r) (apply FUNCTION OLDFUN r))
193`:before-while' (lambda (&rest r) (and (apply FUNCTION r) (apply OLDFUN r)))
194`:before-until' (lambda (&rest r) (or (apply FUNCTION r) (apply OLDFUN r)))
195`:after-while' (lambda (&rest r) (and (apply OLDFUN r) (apply FUNCTION r)))
196`:after-until' (lambda (&rest r) (or (apply OLDFUN r) (apply FUNCTION r)))
197If FUNCTION was already added, do nothing.
198PROPS is an alist of additional properties, among which the following have
199a special meaning:
200- `name': a string or symbol. It can be used to refer to this piece of advice."
201 (declare (debug t)) ;;(indent 2)
202 `(advice--add-function ,where (gv-ref ,place) ,function ,props))
203
204;;;###autoload
205(defun advice--add-function (where ref function props)
206 (unless (advice--member-p function (gv-deref ref))
207 (setf (gv-deref ref)
208 (advice--make where function (gv-deref ref) props))))
209
210(defmacro remove-function (place function)
211 "Remove the FUNCTION piece of advice from PLACE.
212If FUNCTION was not added to PLACE, do nothing.
213Instead of FUNCTION being the actual function, it can also be the `name'
214of the piece of advice."
215 (declare (debug t))
216 (gv-letplace (getter setter) place
217 (macroexp-let2 nil new `(advice--remove-function ,getter ,function)
218 `(unless (eq ,new ,getter) ,(funcall setter new)))))
219
220;;;; Specific application of add-function to `symbol-function' for advice.
221
222(defun advice--subst-main (old new)
223 (if (not (advice--p old))
224 new
225 (let* ((first (advice--car old))
226 (rest (advice--cdr old))
227 (props (advice--props old))
228 (nrest (advice--subst-main rest new)))
229 (if (equal rest nrest) old
230 (advice--make-1 (aref old 1) (aref old 3)
231 first nrest props)))))
232
233(defun advice--defalias-fset (fsetfun symbol newdef)
234 (let* ((olddef (if (fboundp symbol) (symbol-function symbol)))
235 (oldadv
236 (cond
237 ((null (get symbol 'advice--pending))
238 (or olddef
239 (progn
240 (message "Delayed advice activation failed for %s: no data"
241 symbol)
242 nil)))
243 ((or (not olddef) (autoloadp olddef))
244 (prog1 (get symbol 'advice--pending)
245 (put symbol 'advice--pending nil)))
246 (t (message "Dropping left-over advice--pending for %s" symbol)
247 (put symbol 'advice--pending nil)
248 olddef))))
249 (funcall (or fsetfun #'fset) symbol (advice--subst-main oldadv newdef))))
250
251
252;;;###autoload
253(defun advice-add (symbol where function &optional props)
254 "Like `add-function' but for the function named SYMBOL.
255Contrary to `add-function', this will properly handle the cases where SYMBOL
256is defined as a macro, alias, command, ..."
257 ;; TODO:
258 ;; - record the advice location, to display in describe-function.
259 ;; - change all defadvice in lisp/**/*.el.
260 ;; - rewrite advice.el on top of this.
261 ;; - obsolete advice.el.
262 ;; To make advice.el and nadvice.el interoperate properly I see 2 different
263 ;; ways:
264 ;; - keep them separate: complete the defalias-fset-function setter with
265 ;; a matching accessor which both nadvice.el and advice.el will have to use
266 ;; in place of symbol-function. This can probably be made to work, but
267 ;; they have to agree on a "protocol".
268 ;; - layer advice.el on top of nadvice.el. I prefer this approach. the
269 ;; simplest way is to make advice.el build one ad-Advice-foo function for
270 ;; each advised function which is advice-added/removed whenever ad-activate
271 ;; ad-deactivate is called.
272 (let ((f (and (fboundp symbol) (symbol-function symbol))))
273 (cond
274 ((special-form-p f)
275 ;; Not worth the trouble trying to handle this, I think.
276 (error "add-advice failure: %S is a special form" symbol))
277 ((and (symbolp f)
278 (eq 'macro (car-safe (ignore-errors (indirect-function f)))))
279 (let ((newval (cons 'macro (cdr (indirect-function f)))))
280 (put symbol 'advice--saved-rewrite (cons f newval))
281 (fset symbol newval)))
282 ;; `f' might be a pure (hence read-only) cons!
283 ((and (eq 'macro (car-safe f)) (not (ignore-errors (setcdr f (cdr f)) t)))
284 (fset symbol (cons 'macro (cdr f))))
285 ))
286 (let ((f (and (fboundp symbol) (symbol-function symbol))))
287 (add-function where (cond
288 ((eq (car-safe f) 'macro) (cdr f))
289 ;; If the function is not yet defined, we can't yet
290 ;; install the advice.
291 ;; FIXME: If it's an autoloaded command, we also
292 ;; have a problem because we need to load the
293 ;; command to build the interactive-form.
294 ((or (not f) (and (autoloadp f))) ;; (commandp f)
295 (get symbol 'advice--pending))
296 (t (symbol-function symbol)))
297 function props)
298 (add-function :around (get symbol 'defalias-fset-function)
299 #'advice--defalias-fset))
300 nil)
301
302;;;###autoload
303(defun advice-remove (symbol function)
304 "Like `remove-function' but for the function named SYMBOL.
305Contrary to `remove-function', this will work also when SYMBOL is a macro
306and it will not signal an error if SYMBOL is not `fboundp'.
307Instead of the actual function to remove, FUNCTION can also be the `name'
308of the piece of advice."
309 (when (fboundp symbol)
310 (let ((f (symbol-function symbol)))
311 ;; Can't use the `if' place here, because the body is too large,
312 ;; resulting in use of code that only works with lexical-scoping.
313 (remove-function (if (eq (car-safe f) 'macro)
314 (cdr f)
315 (symbol-function symbol))
316 function)
317 (unless (advice--p
318 (if (eq (car-safe f) 'macro) (cdr f) (symbol-function symbol)))
319 ;; Not adviced any more.
320 (remove-function (get symbol 'defalias-fset-function)
321 #'advice--defalias-fset)
322 (if (eq (symbol-function symbol)
323 (cdr (get symbol 'advice--saved-rewrite)))
324 (fset symbol (car (get symbol 'advice--saved-rewrite))))))
325 nil))
326
327;; (defun advice-mapc (fun symbol)
328;; "Apply FUN to every function added as advice to SYMBOL.
329;; FUN is called with a two arguments: the function that was added, and the
330;; properties alist that was specified when it was added."
331;; (let ((def (or (get symbol 'advice--pending)
332;; (if (fboundp symbol) (symbol-function symbol)))))
333;; (while (advice--p def)
334;; (funcall fun (advice--car def) (advice--props def))
335;; (setq def (advice--cdr def)))))
336
337;;;###autoload
338(defun advice-member-p (function symbol)
339 "Return non-nil if advice FUNCTION has been added to function SYMBOL.
340Instead of FUNCTION being the actual function, it can also be the `name'
341of the piece of advice."
342 (advice--member-p function
343 (or (get symbol 'advice--pending)
344 (if (fboundp symbol) (symbol-function symbol)))))
345
346
347(provide 'nadvice)
348;;; nadvice.el ends here
diff --git a/lisp/env.el b/lisp/env.el
index d0d8ed0b998..5f7c61b719a 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -57,31 +57,28 @@ If it is also not t, RET does not exit if it does non-null completion."
57;; History list for VALUE argument to setenv. 57;; History list for VALUE argument to setenv.
58(defvar setenv-history nil) 58(defvar setenv-history nil)
59 59
60(defconst env--substitute-vars-regexp
61 "\\$\\(?:\\(?1:[[:alnum:]_]+\\)\\|{\\(?1:[^{}]+\\)}\\|\\$\\)")
60 62
61(defun substitute-env-vars (string) 63(defun substitute-env-vars (string &optional only-defined)
62 "Substitute environment variables referred to in STRING. 64 "Substitute environment variables referred to in STRING.
63`$FOO' where FOO is an environment variable name means to substitute 65`$FOO' where FOO is an environment variable name means to substitute
64the value of that variable. The variable name should be terminated 66the value of that variable. The variable name should be terminated
65with a character not a letter, digit or underscore; otherwise, enclose 67with a character not a letter, digit or underscore; otherwise, enclose
66the entire variable name in braces. For instance, in `ab$cd-x', 68the entire variable name in braces. For instance, in `ab$cd-x',
67`$cd' is treated as an environment variable. 69`$cd' is treated as an environment variable.
70If ONLY-DEFINED is nil, references to undefined environment variables
71are replaced by the empty string; if it is non-nil, they are left unchanged.
68 72
69Use `$$' to insert a single dollar sign." 73Use `$$' to insert a single dollar sign."
70 (let ((start 0)) 74 (let ((start 0))
71 (while (string-match 75 (while (string-match env--substitute-vars-regexp string start)
72 (eval-when-compile
73 (rx (or (and "$" (submatch (1+ (regexp "[[:alnum:]_]"))))
74 (and "${" (submatch (minimal-match (0+ anything))) "}")
75 "$$")))
76 string start)
77 (cond ((match-beginning 1) 76 (cond ((match-beginning 1)
78 (let ((value (getenv (match-string 1 string)))) 77 (let ((value (getenv (match-string 1 string))))
78 (if (and (null value) only-defined)
79 (setq start (match-end 0))
79 (setq string (replace-match (or value "") t t string) 80 (setq string (replace-match (or value "") t t string)
80 start (+ (match-beginning 0) (length value))))) 81 start (+ (match-beginning 0) (length value))))))
81 ((match-beginning 2)
82 (let ((value (getenv (match-string 2 string))))
83 (setq string (replace-match (or value "") t t string)
84 start (+ (match-beginning 0) (length value)))))
85 (t 82 (t
86 (setq string (replace-match "$" t t string) 83 (setq string (replace-match "$" t t string)
87 start (+ (match-beginning 0) 1))))) 84 start (+ (match-beginning 0) 1)))))
@@ -185,7 +182,7 @@ VARIABLE should be a string. Value is nil if VARIABLE is undefined in
185the environment. Otherwise, value is a string. 182the environment. Otherwise, value is a string.
186 183
187If optional parameter FRAME is non-nil, then it should be a 184If optional parameter FRAME is non-nil, then it should be a
188frame. This function will look up VARIABLE in its 'environment 185frame. This function will look up VARIABLE in its `environment'
189parameter. 186parameter.
190 187
191Otherwise, this function searches `process-environment' for 188Otherwise, this function searches `process-environment' for
diff --git a/lisp/files.el b/lisp/files.el
index 26c5c683b3d..8e8a178caab 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3387,30 +3387,39 @@ It is dangerous if either of these conditions are met:
3387 (setq ok t))) 3387 (setq ok t)))
3388 ok)))))))) 3388 ok))))))))
3389 3389
3390(defun hack-one-local-variable--obsolete (var)
3391 (let ((o (get var 'byte-obsolete-variable)))
3392 (when o
3393 (let ((instead (nth 0 o))
3394 (since (nth 2 o)))
3395 (message "%s is obsolete%s; %s"
3396 var (if since (format " (since %s)" since))
3397 (if (stringp instead) instead
3398 (format "use `%s' instead" instead)))))))
3399
3390(defun hack-one-local-variable (var val) 3400(defun hack-one-local-variable (var val)
3391 "Set local variable VAR with value VAL. 3401 "Set local variable VAR with value VAL.
3392If VAR is `mode', call `VAL-mode' as a function unless it's 3402If VAR is `mode', call `VAL-mode' as a function unless it's
3393already the major mode." 3403already the major mode."
3394 (cond ((eq var 'mode) 3404 (pcase var
3395 (let ((mode (intern (concat (downcase (symbol-name val)) 3405 (`mode
3396 "-mode")))) 3406 (let ((mode (intern (concat (downcase (symbol-name val))
3397 (unless (eq (indirect-function mode) 3407 "-mode"))))
3398 (indirect-function major-mode)) 3408 (unless (eq (indirect-function mode)
3399 (if (memq mode minor-mode-list) 3409 (indirect-function major-mode))
3400 ;; A minor mode must be passed an argument. 3410 (funcall mode))))
3401 ;; Otherwise, if the user enables the minor mode in a 3411 (`eval
3402 ;; major mode hook, this would toggle it off. 3412 (pcase val
3403 (funcall mode 1) 3413 (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
3404 (funcall mode))))) 3414 (save-excursion (eval val)))
3405 ((eq var 'eval) 3415 (_
3406 (save-excursion (eval val))) 3416 (hack-one-local-variable--obsolete var)
3407 (t 3417 ;; Make sure the string has no text properties.
3408 ;; Make sure the string has no text properties. 3418 ;; Some text properties can get evaluated in various ways,
3409 ;; Some text properties can get evaluated in various ways, 3419 ;; so it is risky to put them on with a local variable list.
3410 ;; so it is risky to put them on with a local variable list. 3420 (if (stringp val)
3411 (if (stringp val) 3421 (set-text-properties 0 (length val) nil val))
3412 (set-text-properties 0 (length val) nil val)) 3422 (set (make-local-variable var) val))))
3413 (set (make-local-variable var) val))))
3414 3423
3415;;; Handling directory-local variables, aka project settings. 3424;;; Handling directory-local variables, aka project settings.
3416 3425
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 78204897cf1..5f635e59cdf 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,8 @@
12012-11-08 Katsumi Yamaoka <yamaoka@jpl.org>
2
3 * gnus-art.el (gnus-article-browse-html-parts): Always replace charset
4 in meta tag with the one the part specifies in its header.
5
12012-11-02 Stephen Eglen <S.J.Eglen@damtp.cam.ac.uk> 62012-11-02 Stephen Eglen <S.J.Eglen@damtp.cam.ac.uk>
2 7
3 * gnus-dired.el (gnus-dired-attach): Attach to last used message buffer 8 * gnus-dired.el (gnus-dired-attach): Attach to last used message buffer
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 6c827e070cb..edcd7da2ddd 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -2877,7 +2877,7 @@ message header will be added to the bodies of the \"text/html\" parts."
2877 ;; Add a meta html tag to specify charset and a header. 2877 ;; Add a meta html tag to specify charset and a header.
2878 (cond 2878 (cond
2879 (header 2879 (header
2880 (let (title eheader body hcharset coding force-charset) 2880 (let (title eheader body hcharset coding)
2881 (with-temp-buffer 2881 (with-temp-buffer
2882 (mm-enable-multibyte) 2882 (mm-enable-multibyte)
2883 (setq case-fold-search t) 2883 (setq case-fold-search t)
@@ -2900,8 +2900,7 @@ message header will be added to the bodies of the \"text/html\" parts."
2900 charset) 2900 charset)
2901 title (when title 2901 title (when title
2902 (mm-encode-coding-string title charset)) 2902 (mm-encode-coding-string title charset))
2903 body (mm-encode-coding-string content charset) 2903 body (mm-encode-coding-string content charset))
2904 force-charset t)
2905 (setq hcharset (mm-find-mime-charset-region (point-min) 2904 (setq hcharset (mm-find-mime-charset-region (point-min)
2906 (point-max))) 2905 (point-max)))
2907 (cond ((= (length hcharset) 1) 2906 (cond ((= (length hcharset) 1)
@@ -2932,8 +2931,7 @@ message header will be added to the bodies of the \"text/html\" parts."
2932 body (mm-encode-coding-string 2931 body (mm-encode-coding-string
2933 (mm-decode-coding-string 2932 (mm-decode-coding-string
2934 content body) 2933 content body)
2935 charset) 2934 charset))))
2936 force-charset t)))
2937 (setq charset hcharset 2935 (setq charset hcharset
2938 eheader (mm-encode-coding-string 2936 eheader (mm-encode-coding-string
2939 (buffer-string) coding) 2937 (buffer-string) coding)
@@ -2947,7 +2945,7 @@ message header will be added to the bodies of the \"text/html\" parts."
2947 (mm-disable-multibyte) 2945 (mm-disable-multibyte)
2948 (insert body) 2946 (insert body)
2949 (when charset 2947 (when charset
2950 (mm-add-meta-html-tag handle charset force-charset)) 2948 (mm-add-meta-html-tag handle charset t))
2951 (when title 2949 (when title
2952 (goto-char (point-min)) 2950 (goto-char (point-min))
2953 (unless (search-forward "<title>" nil t) 2951 (unless (search-forward "<title>" nil t)
diff --git a/lisp/ido.el b/lisp/ido.el
index 4ab183b3207..f4f9c27c847 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -3764,7 +3764,11 @@ This is to make them appear as if they were \"virtual buffers\"."
3764 ido-enable-flex-matching 3764 ido-enable-flex-matching
3765 (> (length ido-text) 1) 3765 (> (length ido-text) 1)
3766 (not ido-enable-regexp)) 3766 (not ido-enable-regexp))
3767 (setq re (mapconcat #'regexp-quote (split-string ido-text "") ".*")) 3767 (setq re (concat (regexp-quote (string (aref ido-text 0)))
3768 (mapconcat (lambda (c)
3769 (concat "[^" (string c) "]*"
3770 (regexp-quote (string c))))
3771 (substring ido-text 1) "")))
3768 (if ido-enable-prefix 3772 (if ido-enable-prefix
3769 (setq re (concat "\\`" re))) 3773 (setq re (concat "\\`" re)))
3770 (mapc 3774 (mapc
diff --git a/lisp/mail/emacsbug.el b/lisp/mail/emacsbug.el
index 0066847e995..1d9d098e71c 100644
--- a/lisp/mail/emacsbug.el
+++ b/lisp/mail/emacsbug.el
@@ -60,10 +60,6 @@
60 60
61;; User options end here. 61;; User options end here.
62 62
63(defvar report-emacs-bug-tracker-url "http://debbugs.gnu.org/cgi/"
64 "Base URL of the GNU bugtracker.
65Used for querying duplicates and linking to existing bugs.")
66
67(defvar report-emacs-bug-orig-text nil 63(defvar report-emacs-bug-orig-text nil
68 "The automatically-created initial text of the bug report.") 64 "The automatically-created initial text of the bug report.")
69 65
@@ -444,90 +440,6 @@ and send the mail again%s."
444 (delete-region pos (field-end (1+ pos))))))) 440 (delete-region pos (field-end (1+ pos)))))))
445 441
446 442
447;; Querying the bug database
448
449(defvar report-emacs-bug-bug-alist nil)
450(make-variable-buffer-local 'report-emacs-bug-bug-alist)
451(defvar report-emacs-bug-choice-widget nil)
452(make-variable-buffer-local 'report-emacs-bug-choice-widget)
453
454(defun report-emacs-bug-create-existing-bugs-buffer (bugs keywords)
455 (switch-to-buffer (get-buffer-create "*Existing Emacs Bugs*"))
456 (setq buffer-read-only t)
457 (let ((inhibit-read-only t))
458 (erase-buffer)
459 (setq report-emacs-bug-bug-alist bugs)
460 (widget-insert (propertize (concat "Already known bugs ("
461 keywords "):\n\n")
462 'face 'bold))
463 (if bugs
464 (setq report-emacs-bug-choice-widget
465 (apply 'widget-create 'radio-button-choice
466 :value (caar bugs)
467 (let (items)
468 (dolist (bug bugs)
469 (push (list
470 'url-link
471 :format (concat "Bug#" (number-to-string (nth 2 bug))
472 ": " (cadr bug) "\n %[%v%]\n")
473 ;; FIXME: Why is only the link of the
474 ;; active item clickable?
475 (car bug))
476 items))
477 (nreverse items))))
478 (widget-insert "No bugs matching your keywords found.\n"))
479 (widget-insert "\n")
480 (widget-create 'push-button
481 :notify (lambda (&rest ignore)
482 ;; TODO: Do something!
483 (message "Reporting new bug!"))
484 "Report new bug")
485 (when bugs
486 (widget-insert " ")
487 (widget-create 'push-button
488 :notify (lambda (&rest ignore)
489 (let ((val (widget-value report-emacs-bug-choice-widget)))
490 ;; TODO: Do something!
491 (message "Appending to bug %s!"
492 (nth 2 (assoc val report-emacs-bug-bug-alist)))))
493 "Append to chosen bug"))
494 (widget-insert " ")
495 (widget-create 'push-button
496 :notify (lambda (&rest ignore)
497 (kill-buffer))
498 "Quit reporting bug")
499 (widget-insert "\n"))
500 (use-local-map widget-keymap)
501 (widget-setup)
502 (goto-char (point-min)))
503
504(defun report-emacs-bug-parse-query-results (status keywords)
505 (goto-char (point-min))
506 (let (buglist)
507 (while (re-search-forward "<a href=\"bugreport\\.cgi\\?bug=\\([[:digit:]]+\\)\">\\([^<]+\\)</a>" nil t)
508 (let ((number (match-string 1))
509 (subject (match-string 2)))
510 (when (not (string-match "^#" subject))
511 (push (list
512 ;; first the bug URL
513 (concat report-emacs-bug-tracker-url
514 "bugreport.cgi?bug=" number)
515 ;; then the subject and number
516 subject (string-to-number number))
517 buglist))))
518 (report-emacs-bug-create-existing-bugs-buffer (nreverse buglist) keywords)))
519
520;;;###autoload
521(defun report-emacs-bug-query-existing-bugs (keywords)
522 "Query for KEYWORDS at `report-emacs-bug-tracker-url', and return the result.
523The result is an alist with items of the form (URL SUBJECT NO)."
524 (interactive "sBug keywords (comma separated): ")
525 (url-retrieve (concat report-emacs-bug-tracker-url
526 "pkgreport.cgi?include=subject%3A"
527 (replace-regexp-in-string "[[:space:]]+" "+" keywords)
528 ";package=emacs")
529 'report-emacs-bug-parse-query-results (list keywords)))
530
531(provide 'emacsbug) 443(provide 'emacsbug)
532 444
533;;; emacsbug.el ends here 445;;; emacsbug.el ends here
diff --git a/lisp/minibuf-eldef.el b/lisp/minibuf-eldef.el
index 92d5ec821b0..950c28b227f 100644
--- a/lisp/minibuf-eldef.el
+++ b/lisp/minibuf-eldef.el
@@ -33,13 +33,25 @@
33 33
34;;; Code: 34;;; Code:
35 35
36(defvar minibuffer-eldef-shorten-default nil 36(defvar minibuffer-eldef-shorten-default)
37 "If non-nil, shorten \"(default ...)\" to \"[...]\" in minibuffer prompts.")
38 37
39(defvar minibuffer-default-in-prompt-regexps 38(defun minibuffer-default--in-prompt-regexps ()
40 `(("\\( (default\\(?: is\\)? \\(.*\\))\\):? \\'" 39 `(("\\( (default\\(?: is\\)? \\(.*\\))\\):? \\'"
41 1 ,(if minibuffer-eldef-shorten-default " [\\2]")) 40 1 ,(if minibuffer-eldef-shorten-default " [\\2]"))
42 ("\\( \\[.*\\]\\):? *\\'" 1)) 41 ("\\( \\[.*\\]\\):? *\\'" 1)))
42
43(defcustom minibuffer-eldef-shorten-default nil
44 "If non-nil, shorten \"(default ...)\" to \"[...]\" in minibuffer prompts."
45 :set (lambda (symbol value)
46 (set-default symbol value)
47 (setq-default minibuffer-default-in-prompt-regexps
48 (minibuffer-default--in-prompt-regexps)))
49 :type 'boolean
50 :group 'minibuffer
51 :version "24.3")
52
53(defvar minibuffer-default-in-prompt-regexps
54 (minibuffer-default--in-prompt-regexps)
43 "A list of regexps matching the parts of minibuffer prompts showing defaults. 55 "A list of regexps matching the parts of minibuffer prompts showing defaults.
44When `minibuffer-electric-default-mode' is active, these regexps are 56When `minibuffer-electric-default-mode' is active, these regexps are
45used to identify the portions of prompts to elide. 57used to identify the portions of prompts to elide.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 38347f23f7d..6e704fad807 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -51,6 +51,9 @@
51 51
52;;; Todo: 52;;; Todo:
53 53
54;; - Make *Completions* readable even if some of the completion
55;; entries have LF chars or spaces in them (including at
56;; beginning/end) or are very long.
54;; - for M-x, cycle-sort commands that have no key binding first. 57;; - for M-x, cycle-sort commands that have no key binding first.
55;; - Make things like icomplete-mode or lightning-completion work with 58;; - Make things like icomplete-mode or lightning-completion work with
56;; completion-in-region-mode. 59;; completion-in-region-mode.
@@ -74,6 +77,9 @@
74;; - whether the user wants completion to pay attention to case. 77;; - whether the user wants completion to pay attention to case.
75;; e.g. we may want to make it possible for the user to say "first try 78;; e.g. we may want to make it possible for the user to say "first try
76;; completion case-sensitively, and if that fails, try to ignore case". 79;; completion case-sensitively, and if that fails, try to ignore case".
80;; Maybe the trick is that we should distinguish completion-ignore-case in
81;; try/all-completions (obey user's preference) from its use in
82;; test-completion (obey the underlying object's semantics).
77 83
78;; - add support for ** to pcm. 84;; - add support for ** to pcm.
79;; - Add vc-file-name-completion-table to read-file-name-internal. 85;; - Add vc-file-name-completion-table to read-file-name-internal.
@@ -2048,6 +2054,8 @@ This is only used when the minibuffer area has no active minibuffer.")
2048 process-environment)) 2054 process-environment))
2049 2055
2050(defconst completion--embedded-envvar-re 2056(defconst completion--embedded-envvar-re
2057 ;; We can't reuse env--substitute-vars-regexp because we need to match only
2058 ;; potentially-unfinished envvars at end of string.
2051 (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)" 2059 (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)"
2052 "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'")) 2060 "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'"))
2053 2061
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 874c0aa7fef..caaae5d553e 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1748,20 +1748,26 @@ value of `default-file-modes', without execute permissions."
1748 (or (file-modes filename) 1748 (or (file-modes filename)
1749 (logand (default-file-modes) (tramp-compat-octal-to-decimal "0666")))) 1749 (logand (default-file-modes) (tramp-compat-octal-to-decimal "0666"))))
1750 1750
1751(defun tramp-replace-environment-variables (filename) 1751(defalias 'tramp-replace-environment-variables
1752 "Replace environment variables in FILENAME. 1752 (if (ignore-errors
1753 (equal "${ tramp?}" (substitute-env-vars "${ tramp?}" 'only-defined)))
1754 (lambda (filename)
1755 "Like `substitute-env-vars' with `only-defined' non-nil."
1756 (substitute-env-vars filename 'only-defined))
1757 (lambda (filename)
1758 "Replace environment variables in FILENAME.
1753Return the string with the replaced variables." 1759Return the string with the replaced variables."
1754 (save-match-data 1760 (save-match-data
1755 (let ((idx (string-match "$\\(\\w+\\)" filename))) 1761 (let ((idx (string-match "$\\(\\w+\\)" filename)))
1756 ;; `$' is coded as `$$'. 1762 ;; `$' is coded as `$$'.
1757 (when (and idx 1763 (when (and idx
1758 (or (zerop idx) (not (eq ?$ (aref filename (1- idx))))) 1764 (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
1759 (getenv (match-string 1 filename))) 1765 (getenv (match-string 1 filename)))
1760 (setq filename 1766 (setq filename
1761 (replace-match 1767 (replace-match
1762 (substitute-in-file-name (match-string 0 filename)) 1768 (substitute-in-file-name (match-string 0 filename))
1763 t nil filename))) 1769 t nil filename)))
1764 filename))) 1770 filename)))))
1765 1771
1766;; In XEmacs, electricity is implemented via a key map for ?/ and ?~, 1772;; In XEmacs, electricity is implemented via a key map for ?/ and ?~,
1767;; which calls corresponding functions (see minibuf.el). 1773;; which calls corresponding functions (see minibuf.el).
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index d954cd53e0a..33ef7607671 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -1823,22 +1823,31 @@ nil."
1823 1823
1824;;; Filling 1824;;; Filling
1825 1825
1826(defvar js--filling-paragraph nil)
1827
1828;; FIXME: Such redefinitions are bad style. We should try and use some other
1829;; way to get the same result.
1830(defadvice c-forward-sws (around js-fill-paragraph activate)
1831 (if js--filling-paragraph
1832 (setq ad-return-value (js--forward-syntactic-ws (ad-get-arg 0)))
1833 ad-do-it))
1834
1835(defadvice c-backward-sws (around js-fill-paragraph activate)
1836 (if js--filling-paragraph
1837 (setq ad-return-value (js--backward-syntactic-ws (ad-get-arg 0)))
1838 ad-do-it))
1839
1840(defadvice c-beginning-of-macro (around js-fill-paragraph activate)
1841 (if js--filling-paragraph
1842 (setq ad-return-value (js--beginning-of-macro (ad-get-arg 0)))
1843 ad-do-it))
1844
1826(defun js-c-fill-paragraph (&optional justify) 1845(defun js-c-fill-paragraph (&optional justify)
1827 "Fill the paragraph with `c-fill-paragraph'." 1846 "Fill the paragraph with `c-fill-paragraph'."
1828 (interactive "*P") 1847 (interactive "*P")
1829 ;; FIXME: Such redefinitions are bad style. We should try and use some other 1848 (let ((js--filling-paragraph t)
1830 ;; way to get the same result. 1849 (fill-paragraph-function 'c-fill-paragraph))
1831 (cl-letf (((symbol-function 'c-forward-sws) 1850 (c-fill-paragraph justify)))
1832 (lambda (&optional limit)
1833 (js--forward-syntactic-ws limit)))
1834 ((symbol-function 'c-backward-sws)
1835 (lambda (&optional limit)
1836 (js--backward-syntactic-ws limit)))
1837 ((symbol-function 'c-beginning-of-macro)
1838 (lambda (&optional limit)
1839 (js--beginning-of-macro limit))))
1840 (let ((fill-paragraph-function 'c-fill-paragraph))
1841 (c-fill-paragraph justify))))
1842 1851
1843;;; Type database and Imenu 1852;;; Type database and Imenu
1844 1853
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 3dd9a48bb33..d2f7fc7a059 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -1,4 +1,4 @@
1;;; perl-mode.el --- Perl code editing commands for GNU Emacs 1;;; perl-mode.el --- Perl code editing commands for GNU Emacs -*- coding: utf-8 -*-
2 2
3;; Copyright (C) 1990, 1994, 2001-2012 Free Software Foundation, Inc. 3;; Copyright (C) 1990, 1994, 2001-2012 Free Software Foundation, Inc.
4 4
@@ -102,11 +102,6 @@
102 102
103;;; Code: 103;;; Code:
104 104
105
106(defvar font-lock-comment-face)
107(defvar font-lock-doc-face)
108(defvar font-lock-string-face)
109
110(defgroup perl nil 105(defgroup perl nil
111 "Major mode for editing Perl code." 106 "Major mode for editing Perl code."
112 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) 107 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
@@ -119,16 +114,11 @@
119 114
120(defvar perl-mode-map 115(defvar perl-mode-map
121 (let ((map (make-sparse-keymap))) 116 (let ((map (make-sparse-keymap)))
122 (define-key map "{" 'perl-electric-terminator)
123 (define-key map "}" 'perl-electric-terminator)
124 (define-key map ";" 'perl-electric-terminator)
125 (define-key map ":" 'perl-electric-terminator)
126 (define-key map "\e\C-a" 'perl-beginning-of-function) 117 (define-key map "\e\C-a" 'perl-beginning-of-function)
127 (define-key map "\e\C-e" 'perl-end-of-function) 118 (define-key map "\e\C-e" 'perl-end-of-function)
128 (define-key map "\e\C-h" 'perl-mark-function) 119 (define-key map "\e\C-h" 'perl-mark-function)
129 (define-key map "\e\C-q" 'perl-indent-exp) 120 (define-key map "\e\C-q" 'perl-indent-exp)
130 (define-key map "\177" 'backward-delete-char-untabify) 121 (define-key map "\177" 'backward-delete-char-untabify)
131 (define-key map "\t" 'perl-indent-command)
132 map) 122 map)
133 "Keymap used in Perl mode.") 123 "Keymap used in Perl mode.")
134 124
@@ -158,16 +148,54 @@
158 148
159(defvar perl-imenu-generic-expression 149(defvar perl-imenu-generic-expression
160 '(;; Functions 150 '(;; Functions
161 (nil "^sub\\s-+\\([-A-Za-z0-9+_:]+\\)" 1) 151 (nil "^[ \t]*sub\\s-+\\([-A-Za-z0-9+_:]+\\)" 1)
162 ;;Variables 152 ;;Variables
163 ("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1) 153 ("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1)
164 ("Packages" "^package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1) 154 ("Packages" "^[ \t]*package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1)
165 ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1)) 155 ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1))
166 "Imenu generic expression for Perl mode. See `imenu-generic-expression'.") 156 "Imenu generic expression for Perl mode. See `imenu-generic-expression'.")
167 157
168;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and 158;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and
169;; Jim Campbell <jec@murzim.ca.boeing.com>. 159;; Jim Campbell <jec@murzim.ca.boeing.com>.
170 160
161(defcustom perl-prettify-symbols t
162 "If non-nil, some symbols will be displayed using Unicode chars."
163 :type 'boolean)
164
165(defconst perl--prettify-symbols-alist
166 '(;;("andalso" . ?∧) ("orelse" . ?∨) ("as" . ?≡)("not" . ?¬)
167 ;;("div" . ?÷) ("*" . ?×) ("o" . ?○)
168 ("->" . ?→)
169 ("=>" . ?⇒)
170 ;;("<-" . ?←) ("<>" . ?≠) (">=" . ?≥) ("<=" . ?≤) ("..." . ?⋯)
171 ("::" . ?∷)
172 ))
173
174(defun perl--font-lock-compose-symbol ()
175 "Compose a sequence of ascii chars into a symbol.
176Regexp match data 0 points to the chars."
177 ;; Check that the chars should really be composed into a symbol.
178 (let* ((start (match-beginning 0))
179 (end (match-end 0))
180 (syntaxes (if (eq (char-syntax (char-after start)) ?w)
181 '(?w) '(?. ?\\))))
182 (if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
183 (memq (char-syntax (or (char-after end) ?\ )) syntaxes)
184 (nth 8 (syntax-ppss)))
185 ;; No composition for you. Let's actually remove any composition
186 ;; we may have added earlier and which is now incorrect.
187 (remove-text-properties start end '(composition))
188 ;; That's a symbol alright, so add the composition.
189 (compose-region start end (cdr (assoc (match-string 0)
190 perl--prettify-symbols-alist)))))
191 ;; Return nil because we're not adding any face property.
192 nil)
193
194(defun perl--font-lock-symbols-keywords ()
195 (when perl-prettify-symbols
196 `((,(regexp-opt (mapcar 'car perl--prettify-symbols-alist) t)
197 (0 (perl--font-lock-compose-symbol))))))
198
171(defconst perl-font-lock-keywords-1 199(defconst perl-font-lock-keywords-1
172 '(;; What is this for? 200 '(;; What is this for?
173 ;;("\\(--- .* ---\\|=== .* ===\\)" . font-lock-string-face) 201 ;;("\\(--- .* ---\\|=== .* ===\\)" . font-lock-string-face)
@@ -190,32 +218,32 @@
190 "Subdued level highlighting for Perl mode.") 218 "Subdued level highlighting for Perl mode.")
191 219
192(defconst perl-font-lock-keywords-2 220(defconst perl-font-lock-keywords-2
193 (append perl-font-lock-keywords-1 221 (append
194 (list 222 perl-font-lock-keywords-1
195 ;; 223 `( ;; Fontify keywords, except those fontified otherwise.
196 ;; Fontify keywords, except those fontified otherwise. 224 ,(concat "\\<"
197 (concat "\\<" 225 (regexp-opt '("if" "until" "while" "elsif" "else" "unless"
198 (regexp-opt '("if" "until" "while" "elsif" "else" "unless" 226 "do" "dump" "for" "foreach" "exit" "die"
199 "do" "dump" "for" "foreach" "exit" "die" 227 "BEGIN" "END" "return" "exec" "eval") t)
200 "BEGIN" "END" "return" "exec" "eval") t) 228 "\\>")
201 "\\>") 229 ;;
202 ;; 230 ;; Fontify local and my keywords as types.
203 ;; Fontify local and my keywords as types. 231 ("\\<\\(local\\|my\\)\\>" . font-lock-type-face)
204 '("\\<\\(local\\|my\\)\\>" . font-lock-type-face) 232 ;;
205 ;; 233 ;; Fontify function, variable and file name references.
206 ;; Fontify function, variable and file name references. 234 ("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face)
207 '("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face) 235 ;; Additionally underline non-scalar variables. Maybe this is a bad idea.
208 ;; Additionally underline non-scalar variables. Maybe this is a bad idea. 236 ;;'("[$@%*][#{]?\\(\\sw+\\)" 1 font-lock-variable-name-face)
209 ;;'("[$@%*][#{]?\\(\\sw+\\)" 1 font-lock-variable-name-face) 237 ("[$*]{?\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-variable-name-face)
210 '("[$*]{?\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-variable-name-face) 238 ("\\([@%]\\|\\$#\\)\\(\\sw+\\(::\\sw+\\)*\\)"
211 '("\\([@%]\\|\\$#\\)\\(\\sw+\\(::\\sw+\\)*\\)"
212 (2 (cons font-lock-variable-name-face '(underline)))) 239 (2 (cons font-lock-variable-name-face '(underline))))
213 '("<\\(\\sw+\\)>" 1 font-lock-constant-face) 240 ("<\\(\\sw+\\)>" 1 font-lock-constant-face)
214 ;; 241 ;;
215 ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'. 242 ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'.
216 '("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?" 243 ("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?"
217 (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) 244 (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
218 '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face))) 245 ("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face)
246 ,@(perl--font-lock-symbols-keywords)))
219 "Gaudy level highlighting for Perl mode.") 247 "Gaudy level highlighting for Perl mode.")
220 248
221(defvar perl-font-lock-keywords perl-font-lock-keywords-1 249(defvar perl-font-lock-keywords perl-font-lock-keywords-1
@@ -543,8 +571,10 @@ create a new comment."
543 571
544(defun perl-outline-level () 572(defun perl-outline-level ()
545 (cond 573 (cond
546 ((looking-at "package\\s-") 0) 574 ((looking-at "[ \t]*\\(package\\)\\s-")
547 ((looking-at "sub\\s-") 1) 575 (- (match-beginning 1) (match-beginning 0)))
576 ((looking-at "[ \t]*s\\(ub\\)\\s-")
577 (- (match-beginning 1) (match-beginning 0)))
548 ((looking-at "=head[0-9]") (- (char-before (match-end 0)) ?0)) 578 ((looking-at "=head[0-9]") (- (char-before (match-end 0)) ?0))
549 ((looking-at "=cut") 1) 579 ((looking-at "=cut") 1)
550 (t 3))) 580 (t 3)))
@@ -621,6 +651,11 @@ Turning on Perl mode runs the normal hook `perl-mode-hook'."
621 #'perl-syntax-propertize-function) 651 #'perl-syntax-propertize-function)
622 (add-hook 'syntax-propertize-extend-region-functions 652 (add-hook 'syntax-propertize-extend-region-functions
623 #'syntax-propertize-multiline 'append 'local) 653 #'syntax-propertize-multiline 'append 'local)
654 ;; Electricity.
655 ;; FIXME: setup electric-layout-rules.
656 (set (make-local-variable 'electric-indent-chars)
657 (append '(?\{ ?\} ?\; ?\:) electric-indent-chars))
658 (add-hook 'electric-indent-functions #'perl-electric-noindent-p nil t)
624 ;; Tell imenu how to handle Perl. 659 ;; Tell imenu how to handle Perl.
625 (set (make-local-variable 'imenu-generic-expression) 660 (set (make-local-variable 'imenu-generic-expression)
626 perl-imenu-generic-expression) 661 perl-imenu-generic-expression)
@@ -637,7 +672,11 @@ Turning on Perl mode runs the normal hook `perl-mode-hook'."
637 0 ;Existing comment at bol stays there. 672 0 ;Existing comment at bol stays there.
638 comment-column)) 673 comment-column))
639 674
640(defalias 'electric-perl-terminator 'perl-electric-terminator) 675(define-obsolete-function-alias 'electric-perl-terminator
676 'perl-electric-terminator "22.1")
677(defun perl-electric-noindent-p (char)
678 (unless (eolp) 'no-indent))
679
641(defun perl-electric-terminator (arg) 680(defun perl-electric-terminator (arg)
642 "Insert character and maybe adjust indentation. 681 "Insert character and maybe adjust indentation.
643If at end-of-line, and not in a comment or a quote, correct the indentation." 682If at end-of-line, and not in a comment or a quote, correct the indentation."
@@ -661,6 +700,7 @@ If at end-of-line, and not in a comment or a quote, correct the indentation."
661 (perl-indent-line) 700 (perl-indent-line)
662 (delete-char -1)))) 701 (delete-char -1))))
663 (self-insert-command (prefix-numeric-value arg))) 702 (self-insert-command (prefix-numeric-value arg)))
703(make-obsolete 'perl-electric-terminator 'electric-indent-mode "24.4")
664 704
665;; not used anymore, but may be useful someday: 705;; not used anymore, but may be useful someday:
666;;(defun perl-inside-parens-p () 706;;(defun perl-inside-parens-p ()
@@ -744,6 +784,7 @@ following list:
744 (t 784 (t
745 (message "Use backslash to quote # characters.") 785 (message "Use backslash to quote # characters.")
746 (ding t))))))))) 786 (ding t)))))))))
787(make-obsolete 'perl-indent-command 'indent-according-to-mode "24.4")
747 788
748(defun perl-indent-line (&optional nochange parse-start) 789(defun perl-indent-line (&optional nochange parse-start)
749 "Indent current line as Perl code. 790 "Indent current line as Perl code.
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 84cf7308d75..c9bfcefb748 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1638,6 +1638,8 @@ The variable `ruby-indent-level' controls the amount of indentation.
1638 1638
1639;;;###autoload 1639;;;###autoload
1640(add-to-list 'auto-mode-alist (cons (purecopy "\\.rb\\'") 'ruby-mode)) 1640(add-to-list 'auto-mode-alist (cons (purecopy "\\.rb\\'") 'ruby-mode))
1641;;;###autoload
1642(add-to-list 'auto-mode-alist '("Rakefile\\'" . ruby-mode))
1641 1643
1642;;;###autoload 1644;;;###autoload
1643(dolist (name (list "ruby" "rbx" "jruby" "ruby1.9" "ruby1.8")) 1645(dolist (name (list "ruby" "rbx" "jruby" "ruby1.9" "ruby1.8"))
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 3d5abc4df62..64b87d9e436 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -2802,8 +2802,12 @@ each line with INDENT."
2802 doc)) 2802 doc))
2803 2803
2804;;;###autoload 2804;;;###autoload
2805(defun sql-help () 2805(eval
2806 "Show short help for the SQL modes. 2806 ;; FIXME: This dynamic-docstring-function trick doesn't work for byte-compiled
2807 ;; functions, because of the lazy-loading of docstrings, which strips away
2808 ;; text properties.
2809 '(defun sql-help ()
2810 #("Show short help for the SQL modes.
2807 2811
2808Use an entry function to open an interactive SQL buffer. This buffer is 2812Use an entry function to open an interactive SQL buffer. This buffer is
2809usually named `*SQL*'. The name of the major mode is SQLi. 2813usually named `*SQL*'. The name of the major mode is SQLi.
@@ -2834,32 +2838,23 @@ anything. The name of the major mode is SQL.
2834In this SQL buffer (SQL mode), you can send the region or the entire 2838In this SQL buffer (SQL mode), you can send the region or the entire
2835buffer to the interactive SQL buffer (SQLi mode). The results are 2839buffer to the interactive SQL buffer (SQLi mode). The results are
2836appended to the SQLi buffer without disturbing your SQL buffer." 2840appended to the SQLi buffer without disturbing your SQL buffer."
2841 0 1 (dynamic-docstring-function sql--make-help-docstring))
2837 (interactive) 2842 (interactive)
2843 (describe-function 'sql-help)))
2838 2844
2839 ;; Insert references to loaded products into the help buffer string 2845(defun sql--make-help-docstring (doc _fun)
2840 (let ((doc (documentation 'sql-help t)) 2846 "Insert references to loaded products into the help buffer string."
2841 changedp) 2847
2842 (setq changedp nil) 2848 ;; Insert FREE software list
2843 2849 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]FREE\\s-*\n" doc 0)
2844 ;; Insert FREE software list 2850 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) t)
2845 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]FREE\\s-*\n" doc 0) 2851 t t doc 0)))
2846 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) t) 2852
2847 t t doc 0) 2853 ;; Insert non-FREE software list
2848 changedp t)) 2854 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]NONFREE\\s-*\n" doc 0)
2849 2855 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) nil)
2850 ;; Insert non-FREE software list 2856 t t doc 0)))
2851 (when (string-match "^\\(\\s-*\\)[\\\\][\\\\]NONFREE\\s-*\n" doc 0) 2857 doc)
2852 (setq doc (replace-match (sql-help-list-products (match-string 1 doc) nil)
2853 t t doc 0)
2854 changedp t))
2855
2856 ;; If we changed the help text, save the change so that the help
2857 ;; sub-system will see it
2858 (when changedp
2859 (put 'sql-help 'function-documentation doc)))
2860
2861 ;; Call help on this function
2862 (describe-function 'sql-help))
2863 2858
2864(defun sql-read-passwd (prompt &optional default) 2859(defun sql-read-passwd (prompt &optional default)
2865 "Read a password using PROMPT. Optional DEFAULT is password to start with." 2860 "Read a password using PROMPT. Optional DEFAULT is password to start with."
diff --git a/lisp/server.el b/lisp/server.el
index 7a356a90378..c78e3e376aa 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -842,6 +842,15 @@ This handles splitting the command if it would be bigger than
842 (unless (assq w window-system-initialization-alist) 842 (unless (assq w window-system-initialization-alist)
843 (setq w nil)) 843 (setq w nil))
844 844
845 ;; Special case for ns. This is because DISPLAY may not be set at all
846 ;; which in the ns case isn't an error. The variable display then becomes
847 ;; the fully qualified hostname, which make-frame-on-display below
848 ;; does not understand and throws an error.
849 ;; It may also be a valid X display, but if Emacs is compiled for ns, it
850 ;; can not make X frames.
851 (if (featurep 'ns-win)
852 (setq w 'ns display "ns"))
853
845 (cond (w 854 (cond (w
846 ;; Flag frame as client-created, but use a dummy client. 855 ;; Flag frame as client-created, but use a dummy client.
847 ;; This will prevent the frame from being deleted when 856 ;; This will prevent the frame from being deleted when
diff --git a/lisp/ses.el b/lisp/ses.el
index 7cdac74e310..27b906d22e3 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -278,6 +278,7 @@ default printer and then modify its output.")
278 ses--default-printer 278 ses--default-printer
279 ses--deferred-narrow ses--deferred-recalc 279 ses--deferred-narrow ses--deferred-recalc
280 ses--deferred-write ses--file-format 280 ses--deferred-write ses--file-format
281 ses--named-cell-hashmap
281 (ses--header-hscroll . -1) ; Flag for "initial recalc needed" 282 (ses--header-hscroll . -1) ; Flag for "initial recalc needed"
282 ses--header-row ses--header-string ses--linewidth 283 ses--header-row ses--header-string ses--linewidth
283 ses--numcols ses--numrows ses--symbolic-formulas 284 ses--numcols ses--numrows ses--symbolic-formulas
@@ -511,9 +512,22 @@ PROPERTY-NAME."
511 `(aref ses--col-printers ,col)) 512 `(aref ses--col-printers ,col))
512 513
513(defmacro ses-sym-rowcol (sym) 514(defmacro ses-sym-rowcol (sym)
514 "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). 515 "From a cell-symbol SYM, gets the cons (row . col). A1 => (0 . 0). Result
515Result is nil if SYM is not a symbol that names a cell." 516is nil if SYM is not a symbol that names a cell."
516 `(and (symbolp ,sym) (get ,sym 'ses-cell))) 517 `(let ((rc (and (symbolp ,sym) (get ,sym 'ses-cell))))
518 (if (eq rc :ses-named)
519 (gethash ,sym ses--named-cell-hashmap)
520 rc)))
521
522(defun ses-is-cell-sym-p (sym)
523 "Check whether SYM point at a cell of this spread sheet."
524 (let ((rowcol (get sym 'ses-cell)))
525 (and rowcol
526 (if (eq rowcol :ses-named)
527 (and ses--named-cell-hashmap (gethash sym ses--named-cell-hashmap))
528 (and (< (car rowcol) ses--numrows)
529 (< (cdr rowcol) ses--numcols)
530 (eq (ses-cell-symbol (car rowcol) (cdr rowcol)) sym))))))
517 531
518(defmacro ses-cell (sym value formula printer references) 532(defmacro ses-cell (sym value formula printer references)
519 "Load a cell SYM from the spreadsheet file. Does not recompute VALUE from 533 "Load a cell SYM from the spreadsheet file. Does not recompute VALUE from
@@ -682,6 +696,28 @@ for this spreadsheet."
682 "Produce a symbol that names the cell (ROW,COL). (0,0) => 'A1." 696 "Produce a symbol that names the cell (ROW,COL). (0,0) => 'A1."
683 (intern (concat (ses-column-letter col) (number-to-string (1+ row))))) 697 (intern (concat (ses-column-letter col) (number-to-string (1+ row)))))
684 698
699(defun ses-decode-cell-symbol (str)
700 "Decode a symbol \"A1\" => (0,0). Returns `nil' if STR is not a
701 canonical cell name. Does not save match data."
702 (let (case-fold-search)
703 (and (string-match "\\`\\([A-Z]+\\)\\([0-9]+\\)\\'" str)
704 (let* ((col-str (match-string-no-properties 1 str))
705 (col 0)
706 (col-offset 0)
707 (col-base 1)
708 (col-idx (1- (length col-str)))
709 (row (1- (string-to-number (match-string-no-properties 2 str)))))
710 (and (>= row 0)
711 (progn
712 (while
713 (progn
714 (setq col (+ col (* (- (aref col-str col-idx) ?A) col-base))
715 col-base (* col-base 26)
716 col-idx (1- col-idx))
717 (and (>= col-idx 0)
718 (setq col (+ col col-base)))))
719 (cons row col)))))))
720
685(defun ses-create-cell-variable-range (minrow maxrow mincol maxcol) 721(defun ses-create-cell-variable-range (minrow maxrow mincol maxcol)
686 "Create buffer-local variables for cells. This is undoable." 722 "Create buffer-local variables for cells. This is undoable."
687 (push `(apply ses-destroy-cell-variable-range ,minrow ,maxrow ,mincol ,maxcol) 723 (push `(apply ses-destroy-cell-variable-range ,minrow ,maxrow ,mincol ,maxcol)
@@ -704,7 +740,11 @@ row and column of the cell, with numbering starting from 0.
704Return nil in case of failure." 740Return nil in case of failure."
705 (unless (local-variable-p sym) 741 (unless (local-variable-p sym)
706 (make-local-variable sym) 742 (make-local-variable sym)
707 (put sym 'ses-cell (cons row col)))) 743 (if (let (case-fold-search) (string-match "\\`[A-Z]+[0-9]+\\'" (symbol-name sym)))
744 (put sym 'ses-cell (cons row col))
745 (put sym 'ses-cell :ses-named)
746 (setq ses--named-cell-hashmap (or ses--named-cell-hashmap (make-hash-table :test 'eq)))
747 (puthash sym (cons row col) ses--named-cell-hashmap))))
708 748
709;; We do not delete the ses-cell properties for the cell-variables, in 749;; We do not delete the ses-cell properties for the cell-variables, in
710;; case a formula that refers to this cell is in the kill-ring and is 750;; case a formula that refers to this cell is in the kill-ring and is
@@ -3211,27 +3251,36 @@ highlighted range in the spreadsheet."
3211(defun ses-rename-cell (new-name &optional cell) 3251(defun ses-rename-cell (new-name &optional cell)
3212 "Rename current cell." 3252 "Rename current cell."
3213 (interactive "*SEnter new name: ") 3253 (interactive "*SEnter new name: ")
3214 (and (local-variable-p new-name) 3254 (or
3215 (ses-sym-rowcol new-name) 3255 (and (local-variable-p new-name)
3216 ;; this test is needed because ses-cell property of deleted cells 3256 (ses-is-cell-sym-p new-name)
3217 ;; is not deleted in case of subsequent undo 3257 (error "Already a cell name"))
3218 (memq new-name ses--renamed-cell-symb-list) 3258 (and (boundp new-name)
3219 (error "Already a cell name")) 3259 (null (yes-or-no-p (format "`%S' is already bound outside this buffer, continue? "
3220 (and (boundp new-name) 3260 new-name)))
3221 (null (yes-or-no-p (format "`%S' is already bound outside this buffer, continue? " 3261 (error "Already a bound cell name")))
3222 new-name))) 3262 (let* (curcell
3223 (error "Already a bound cell name")) 3263 (sym (if (ses-cell-p cell)
3224 (let* ((sym (if (ses-cell-p cell)
3225 (ses-cell-symbol cell) 3264 (ses-cell-symbol cell)
3226 (setq cell nil) 3265 (setq cell nil
3266 curcell t)
3227 (ses-check-curcell) 3267 (ses-check-curcell)
3228 ses--curcell)) 3268 ses--curcell))
3229 (rowcol (ses-sym-rowcol sym)) 3269 (rowcol (ses-sym-rowcol sym))
3230 (row (car rowcol)) 3270 (row (car rowcol))
3231 (col (cdr rowcol))) 3271 (col (cdr rowcol))
3232 (setq cell (or cell (ses-get-cell row col))) 3272 new-rowcol old-name)
3233 (push `(ses-rename-cell ,(ses-cell-symbol cell) ,cell) buffer-undo-list) 3273 (setq cell (or cell (ses-get-cell row col))
3234 (put new-name 'ses-cell rowcol) 3274 old-name (ses-cell-symbol cell)
3275 new-rowcol (ses-decode-cell-symbol (symbol-name new-name)))
3276 (if new-rowcol
3277 (if (equal new-rowcol rowcol)
3278 (put new-name 'ses-cell rowcol)
3279 (error "Not a valid name for this cell location"))
3280 (setq ses--named-cell-hashmap (or ses--named-cell-hashmap (make-hash-table :test 'eq)))
3281 (put new-name 'ses-cell :ses-named)
3282 (puthash new-name rowcol ses--named-cell-hashmap))
3283 (push `(ses-rename-cell ,old-name ,cell) buffer-undo-list)
3235 ;; replace name by new name in formula of cells refering to renamed cell 3284 ;; replace name by new name in formula of cells refering to renamed cell
3236 (dolist (ref (ses-cell-references cell)) 3285 (dolist (ref (ses-cell-references cell))
3237 (let* ((x (ses-sym-rowcol ref)) 3286 (let* ((x (ses-sym-rowcol ref))
@@ -3251,9 +3300,8 @@ highlighted range in the spreadsheet."
3251 (push new-name ses--renamed-cell-symb-list) 3300 (push new-name ses--renamed-cell-symb-list)
3252 (set new-name (symbol-value sym)) 3301 (set new-name (symbol-value sym))
3253 (aset cell 0 new-name) 3302 (aset cell 0 new-name)
3254 (put sym 'ses-cell nil)
3255 (makunbound sym) 3303 (makunbound sym)
3256 (setq sym new-name) 3304 (and curcell (setq ses--curcell new-name))
3257 (let* ((pos (point)) 3305 (let* ((pos (point))
3258 (inhibit-read-only t) 3306 (inhibit-read-only t)
3259 (col (current-column)) 3307 (col (current-column))
diff --git a/lisp/subr.el b/lisp/subr.el
index d328b7cddf5..ebfcfbc0930 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -222,9 +222,7 @@ Then evaluate RESULT to get return value, default nil.
222 (let ((,(car spec) (car ,temp))) 222 (let ((,(car spec) (car ,temp)))
223 ,@body 223 ,@body
224 (setq ,temp (cdr ,temp)))) 224 (setq ,temp (cdr ,temp))))
225 ,@(if (cdr (cdr spec)) 225 ,@(cdr (cdr spec)))
226 ;; FIXME: This let often leads to "unused var" warnings.
227 `((let ((,(car spec) nil)) ,@(cdr (cdr spec))))))
228 `(let ((,temp ,(nth 1 spec)) 226 `(let ((,temp ,(nth 1 spec))
229 ,(car spec)) 227 ,(car spec))
230 (while ,temp 228 (while ,temp
@@ -2657,13 +2655,17 @@ See also `locate-user-emacs-file'.")
2657 2655
2658(defun locate-user-emacs-file (new-name &optional old-name) 2656(defun locate-user-emacs-file (new-name &optional old-name)
2659 "Return an absolute per-user Emacs-specific file name. 2657 "Return an absolute per-user Emacs-specific file name.
2660If OLD-NAME is non-nil and ~/OLD-NAME exists, return ~/OLD-NAME. 2658If NEW-NAME exists in `user-emacs-directory', return it.
2659Else If OLD-NAME is non-nil and ~/OLD-NAME exists, return ~/OLD-NAME.
2661Else return NEW-NAME in `user-emacs-directory', creating the 2660Else return NEW-NAME in `user-emacs-directory', creating the
2662directory if it does not exist." 2661directory if it does not exist."
2663 (convert-standard-filename 2662 (convert-standard-filename
2664 (let* ((home (concat "~" (or init-file-user ""))) 2663 (let* ((home (concat "~" (or init-file-user "")))
2665 (at-home (and old-name (expand-file-name old-name home)))) 2664 (at-home (and old-name (expand-file-name old-name home)))
2666 (if (and at-home (file-readable-p at-home)) 2665 (bestname (abbreviate-file-name
2666 (expand-file-name new-name user-emacs-directory))))
2667 (if (and at-home (not (file-readable-p bestname))
2668 (file-readable-p at-home))
2667 at-home 2669 at-home
2668 ;; Make sure `user-emacs-directory' exists, 2670 ;; Make sure `user-emacs-directory' exists,
2669 ;; unless we're in batch mode or dumping Emacs 2671 ;; unless we're in batch mode or dumping Emacs
@@ -2677,8 +2679,7 @@ directory if it does not exist."
2677 (set-default-file-modes ?\700) 2679 (set-default-file-modes ?\700)
2678 (make-directory user-emacs-directory)) 2680 (make-directory user-emacs-directory))
2679 (set-default-file-modes umask)))) 2681 (set-default-file-modes umask))))
2680 (abbreviate-file-name 2682 bestname))))
2681 (expand-file-name new-name user-emacs-directory))))))
2682 2683
2683;;;; Misc. useful functions. 2684;;;; Misc. useful functions.
2684 2685
@@ -2808,6 +2809,12 @@ Otherwise, return nil."
2808Otherwise, return nil." 2809Otherwise, return nil."
2809 (and (memq object '(nil t)) t)) 2810 (and (memq object '(nil t)) t))
2810 2811
2812(defun special-form-p (object)
2813 "Non-nil if and only if OBJECT is a special form."
2814 (if (and (symbolp object) (fboundp object))
2815 (setq object (indirect-function object)))
2816 (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled)))
2817
2811(defun field-at-pos (pos) 2818(defun field-at-pos (pos)
2812 "Return the field at position POS, taking stickiness etc into account." 2819 "Return the field at position POS, taking stickiness etc into account."
2813 (let ((raw-field (get-char-property (field-beginning pos) 'field))) 2820 (let ((raw-field (get-char-property (field-beginning pos) 'field)))
diff --git a/lisp/term.el b/lisp/term.el
index 7567bd38f5a..e6466b8fa95 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -452,7 +452,7 @@ state 4: term-terminal-parameter contains pending output.")
452 "A queue of strings whose echo we want suppressed.") 452 "A queue of strings whose echo we want suppressed.")
453(defvar term-terminal-parameter) 453(defvar term-terminal-parameter)
454(defvar term-terminal-previous-parameter) 454(defvar term-terminal-previous-parameter)
455(defvar term-current-face 'term-face) 455(defvar term-current-face 'term)
456(defvar term-scroll-start 0 "Top-most line (inclusive) of scrolling region.") 456(defvar term-scroll-start 0 "Top-most line (inclusive) of scrolling region.")
457(defvar term-scroll-end) ; Number of line (zero-based) after scrolling region. 457(defvar term-scroll-end) ; Number of line (zero-based) after scrolling region.
458(defvar term-pager-count nil 458(defvar term-pager-count nil
@@ -759,7 +759,7 @@ Buffer local variable.")
759 759
760;;; Faces 760;;; Faces
761(defvar ansi-term-color-vector 761(defvar ansi-term-color-vector
762 [term-face 762 [term
763 term-color-black 763 term-color-black
764 term-color-red 764 term-color-red
765 term-color-green 765 term-color-green
@@ -770,18 +770,20 @@ Buffer local variable.")
770 term-color-white]) 770 term-color-white])
771 771
772(defcustom term-default-fg-color nil 772(defcustom term-default-fg-color nil
773 "If non-nil, default color for foreground in Term mode. 773 "If non-nil, default color for foreground in Term mode."
774This is deprecated in favor of customizing the `term-face' face."
775 :group 'term 774 :group 'term
776 :type 'string) 775 :type 'string)
776(make-obsolete-variable 'term-default-fg-color "use the face `term' instead."
777 "24.3")
777 778
778(defcustom term-default-bg-color nil 779(defcustom term-default-bg-color nil
779 "If non-nil, default color for foreground in Term mode. 780 "If non-nil, default color for foreground in Term mode."
780This is deprecated in favor of customizing the `term-face' face."
781 :group 'term 781 :group 'term
782 :type 'string) 782 :type 'string)
783(make-obsolete-variable 'term-default-bg-color "use the face `term' instead."
784 "24.3")
783 785
784(defface term-face 786(defface term
785 `((t 787 `((t
786 :foreground ,term-default-fg-color 788 :foreground ,term-default-fg-color
787 :background ,term-default-bg-color 789 :background ,term-default-bg-color
@@ -988,7 +990,7 @@ is buffer-local."
988 dt)) 990 dt))
989 991
990(defun term-ansi-reset () 992(defun term-ansi-reset ()
991 (setq term-current-face 'term-face) 993 (setq term-current-face 'term)
992 (setq term-ansi-current-underline nil) 994 (setq term-ansi-current-underline nil)
993 (setq term-ansi-current-bold nil) 995 (setq term-ansi-current-bold nil)
994 (setq term-ansi-current-reverse nil) 996 (setq term-ansi-current-reverse nil)
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 49b76a8e3bc..26c64ce2ad3 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -178,7 +178,7 @@ when editing big diffs)."
178 ["Unified -> Context" diff-unified->context 178 ["Unified -> Context" diff-unified->context
179 :help "Convert unified diffs to context diffs"] 179 :help "Convert unified diffs to context diffs"]
180 ;;["Fixup Headers" diff-fixup-modifs (not buffer-read-only)] 180 ;;["Fixup Headers" diff-fixup-modifs (not buffer-read-only)]
181 ["Remove trailing whitespace" diff-remove-trailing-whitespace 181 ["Remove trailing whitespace" diff-delete-trailing-whitespace
182 :help "Remove trailing whitespace problems introduced by the diff"] 182 :help "Remove trailing whitespace problems introduced by the diff"]
183 ["Show trailing whitespace" whitespace-mode 183 ["Show trailing whitespace" whitespace-mode
184 :style toggle :selected (bound-and-true-p whitespace-mode) 184 :style toggle :selected (bound-and-true-p whitespace-mode)
@@ -2048,35 +2048,71 @@ I.e. like `add-change-log-entry-other-window' but applied to all hunks."
2048 ;; When there's no more hunks, diff-hunk-next signals an error. 2048 ;; When there's no more hunks, diff-hunk-next signals an error.
2049 (error nil)))) 2049 (error nil))))
2050 2050
2051(defun diff-remove-trailing-whitespace () 2051(defun diff-delete-trailing-whitespace (&optional other-file)
2052 "When on a buffer that contains a diff, inspects the 2052 "Remove trailing whitespace from lines modified in this diff.
2053differences and removes trailing whitespace (spaces, tabs) from 2053This edits both the current Diff mode buffer and the patched
2054the lines modified or introduced by this diff. Shows a message 2054source file(s). If `diff-jump-to-old-file' is non-nil, edit the
2055with the name of the altered buffers, which are unsaved. If a 2055original (unpatched) source file instead. With a prefix argument
2056file referenced on the diff has no buffer and needs to be fixed, 2056OTHER-FILE, flip the choice of which source file to edit.
2057a buffer visiting that file is created." 2057
2058 (interactive) 2058If a file referenced in the diff has no buffer and needs to be
2059 ;; We assume that the diff header has no trailing whitespace. 2059fixed, visit it in a buffer."
2060 (let ((modified-buffers nil)) 2060 (interactive "P")
2061 (save-excursion 2061 (save-excursion
2062 (goto-char (point-min)) 2062 (goto-char (point-min))
2063 (while (re-search-forward "^[+!>].*[ \t]+$" (point-max) t) 2063 (let* ((other (diff-xor other-file diff-jump-to-old-file))
2064 (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,_switched) 2064 (modified-buffers nil)
2065 (diff-find-source-location t t))) 2065 (style (save-excursion
2066 (when line-offset 2066 (when (re-search-forward diff-hunk-header-re nil t)
2067 (with-current-buffer buf 2067 (goto-char (match-beginning 0))
2068 (save-excursion 2068 (diff-hunk-style))))
2069 (goto-char (+ (car pos) (cdr src))) 2069 (regexp (concat "^[" (if other "-<" "+>") "!]"
2070 (beginning-of-line) 2070 (if (eq style 'context) " " "")
2071 (when (re-search-forward "\\([ \t]+\\)$" (line-end-position) t) 2071 ".*?\\([ \t]+\\)$"))
2072 (unless (memq buf modified-buffers) 2072 (inhibit-read-only t)
2073 (push buf modified-buffers)) 2073 (end-marker (make-marker))
2074 (replace-match "")))))))) 2074 hunk-end)
2075 (if modified-buffers 2075 ;; Move to the first hunk.
2076 (message "Deleted new trailing whitespace from: %s" 2076 (re-search-forward diff-hunk-header-re nil 1)
2077 (mapconcat (lambda (buf) (concat "`" (buffer-name buf) "'")) 2077 (while (progn (save-excursion
2078 modified-buffers " ")) 2078 (re-search-forward diff-hunk-header-re nil 1)
2079 (message "No trailing whitespace fixes needed.")))) 2079 (setq hunk-end (point)))
2080 (< (point) hunk-end))
2081 ;; For context diffs, search only in the appropriate half of
2082 ;; the hunk. For other diffs, search within the entire hunk.
2083 (if (not (eq style 'context))
2084 (set-marker end-marker hunk-end)
2085 (let ((mid-hunk
2086 (save-excursion
2087 (re-search-forward diff-context-mid-hunk-header-re hunk-end)
2088 (point))))
2089 (if other
2090 (set-marker end-marker mid-hunk)
2091 (goto-char mid-hunk)
2092 (set-marker end-marker hunk-end))))
2093 (while (re-search-forward regexp end-marker t)
2094 (let ((match-data (match-data)))
2095 (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,_switched)
2096 (diff-find-source-location other-file)))
2097 (when line-offset
2098 ;; Remove the whitespace in the Diff mode buffer.
2099 (set-match-data match-data)
2100 (replace-match "" t t nil 1)
2101 ;; Remove the whitespace in the source buffer.
2102 (with-current-buffer buf
2103 (save-excursion
2104 (goto-char (+ (car pos) (cdr src)))
2105 (beginning-of-line)
2106 (when (re-search-forward "\\([ \t]+\\)$" (line-end-position) t)
2107 (unless (memq buf modified-buffers)
2108 (push buf modified-buffers))
2109 (replace-match ""))))))))
2110 (goto-char hunk-end))
2111 (if modified-buffers
2112 (message "Deleted trailing whitespace from %s."
2113 (mapconcat (lambda (buf) (concat "`" (buffer-name buf) "'"))
2114 modified-buffers ", "))
2115 (message "No trailing whitespace to delete.")))))
2080 2116
2081;; provide the package 2117;; provide the package
2082(provide 'diff-mode) 2118(provide 'diff-mode)
diff --git a/lisp/woman.el b/lisp/woman.el
index e41c489dbfa..974a7d72465 100644
--- a/lisp/woman.el
+++ b/lisp/woman.el
@@ -2253,7 +2253,9 @@ Currently set only from '\" t in the first line of the source file.")
2253 (set-face-font 'woman-symbol woman-symbol-font 2253 (set-face-font 'woman-symbol woman-symbol-font
2254 (and (frame-live-p woman-frame) woman-frame))) 2254 (and (frame-live-p woman-frame) woman-frame)))
2255 2255
2256 ;; Set syntax and display tables: 2256 (setq-local adaptive-fill-mode nil) ; No special "%" "#" etc filling.
2257
2258 ;; Set syntax and display tables:
2257 (set-syntax-table woman-syntax-table) 2259 (set-syntax-table woman-syntax-table)
2258 (woman-set-buffer-display-table) 2260 (woman-set-buffer-display-table)
2259 2261