diff options
| author | Stefan Monnier | 2013-08-04 16:18:11 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-08-04 16:18:11 -0400 |
| commit | 671d5c16547d16bef2efa056705bd35b5feacc29 (patch) | |
| tree | 4bc2c3774ce9914f21508d0e2a83e25504dbc1db /lisp | |
| parent | e443729d658ee2b9e0f55bbbb90241819bf516a6 (diff) | |
| download | emacs-671d5c16547d16bef2efa056705bd35b5feacc29.tar.gz emacs-671d5c16547d16bef2efa056705bd35b5feacc29.zip | |
* lisp/subr.el (macrop): New function.
(text-clone--maintaining): New var.
(text-clone--maintain): Rename from text-clone-maintain. Use it
instead of inhibit-modification-hooks.
* lisp/emacs-lisp/nadvice.el (advice--normalize): For aliases to macros, use
a proxy, so as handle autoloads and redefinitions of the target.
(advice--defalias-fset, advice-remove): Use advice--symbol-function.
* lisp/emacs-lisp/pcase.el (pcase-mutually-exclusive-predicates):
Remove bogus (arrayp . stringp) pair. Add entries for `vectorp'.
(pcase--mutually-exclusive-p): New function.
(pcase--split-consp): Use it.
(pcase--split-pred): Use it. Optimize the case where `pat' is a qpat
mutually exclusive with the current predicate.
* test/automated/advice-tests.el (advice-tests-nadvice): Test removal
before definition.
(advice-tests-macroaliases): New test.
* lisp/emacs-lisp/edebug.el (edebug-lookup-function): Remove function.
(edebug-macrop): Remove. Use `macrop' instead.
* lisp/emacs-lisp/advice.el (ad-subr-p): Remove. Use `subrp' instead.
(ad-macro-p):
* lisp/eshell/esh-cmd.el (eshell-macrop):
* lisp/apropos.el (apropos-macrop): Remove. Use `macrop' instead.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 25 | ||||
| -rw-r--r-- | lisp/apropos.el | 13 | ||||
| -rw-r--r-- | lisp/emacs-lisp/advice.el | 30 | ||||
| -rw-r--r-- | lisp/emacs-lisp/edebug.el | 15 | ||||
| -rw-r--r-- | lisp/emacs-lisp/nadvice.el | 23 | ||||
| -rw-r--r-- | lisp/emacs-lisp/pcase.el | 31 | ||||
| -rw-r--r-- | lisp/eshell/esh-cmd.el | 10 | ||||
| -rw-r--r-- | lisp/subr.el | 24 |
8 files changed, 82 insertions, 89 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index dc1fa09b316..66bf7422b0d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,30 @@ | |||
| 1 | 2013-08-04 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2013-08-04 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * subr.el (macrop): New function. | ||
| 4 | (text-clone--maintaining): New var. | ||
| 5 | (text-clone--maintain): Rename from text-clone-maintain. Use it | ||
| 6 | instead of inhibit-modification-hooks. | ||
| 7 | |||
| 8 | * emacs-lisp/nadvice.el (advice--normalize): For aliases to macros, use | ||
| 9 | a proxy, so as handle autoloads and redefinitions of the target. | ||
| 10 | (advice--defalias-fset, advice-remove): Use advice--symbol-function. | ||
| 11 | |||
| 12 | * emacs-lisp/pcase.el (pcase-mutually-exclusive-predicates): | ||
| 13 | Remove bogus (arrayp . stringp) pair. Add entries for `vectorp'. | ||
| 14 | (pcase--mutually-exclusive-p): New function. | ||
| 15 | (pcase--split-consp): Use it. | ||
| 16 | (pcase--split-pred): Use it. Optimize the case where `pat' is a qpat | ||
| 17 | mutually exclusive with the current predicate. | ||
| 18 | |||
| 19 | * emacs-lisp/edebug.el (edebug-lookup-function): Remove function. | ||
| 20 | (edebug-macrop): Remove. Use `macrop' instead. | ||
| 21 | * emacs-lisp/advice.el (ad-subr-p): Remove. Use `subrp' instead. | ||
| 22 | (ad-macro-p): | ||
| 23 | * eshell/esh-cmd.el (eshell-macrop): | ||
| 24 | * apropos.el (apropos-macrop): Remove. Use `macrop' instead. | ||
| 25 | |||
| 26 | 2013-08-04 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 27 | |||
| 3 | * emacs-lisp/nadvice.el (advice-function-mapc): Rename from advice-mapc. | 28 | * emacs-lisp/nadvice.el (advice-function-mapc): Rename from advice-mapc. |
| 4 | (advice-mapc): New function, using it. | 29 | (advice-mapc): New function, using it. |
| 5 | (advice-function-member-p): New function. | 30 | (advice-function-member-p): New function. |
diff --git a/lisp/apropos.el b/lisp/apropos.el index 000d2d87d05..7a1a6f6a75a 100644 --- a/lisp/apropos.el +++ b/lisp/apropos.el | |||
| @@ -1121,7 +1121,7 @@ If non-nil TEXT is a string that will be printed as a heading." | |||
| 1121 | (apropos-print-doc 2 | 1121 | (apropos-print-doc 2 |
| 1122 | (if (commandp symbol) | 1122 | (if (commandp symbol) |
| 1123 | 'apropos-command | 1123 | 'apropos-command |
| 1124 | (if (apropos-macrop symbol) | 1124 | (if (macrop symbol) |
| 1125 | 'apropos-macro | 1125 | 'apropos-macro |
| 1126 | 'apropos-function)) | 1126 | 'apropos-function)) |
| 1127 | (not nosubst)) | 1127 | (not nosubst)) |
| @@ -1139,17 +1139,6 @@ If non-nil TEXT is a string that will be printed as a heading." | |||
| 1139 | (prog1 apropos-accumulator | 1139 | (prog1 apropos-accumulator |
| 1140 | (setq apropos-accumulator ()))) ; permit gc | 1140 | (setq apropos-accumulator ()))) ; permit gc |
| 1141 | 1141 | ||
| 1142 | (defun apropos-macrop (symbol) | ||
| 1143 | "Return t if SYMBOL is a Lisp macro." | ||
| 1144 | (and (fboundp symbol) | ||
| 1145 | (consp (setq symbol | ||
| 1146 | (symbol-function symbol))) | ||
| 1147 | (or (eq (car symbol) 'macro) | ||
| 1148 | (if (autoloadp symbol) | ||
| 1149 | (memq (nth 4 symbol) | ||
| 1150 | '(macro t)))))) | ||
| 1151 | |||
| 1152 | |||
| 1153 | (defun apropos-print-doc (i type do-keys) | 1142 | (defun apropos-print-doc (i type do-keys) |
| 1154 | (let ((doc (nth i apropos-item))) | 1143 | (let ((doc (nth i apropos-item))) |
| 1155 | (when (stringp doc) | 1144 | (when (stringp doc) |
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el index eb1d63e788b..861054e777f 100644 --- a/lisp/emacs-lisp/advice.el +++ b/lisp/emacs-lisp/advice.el | |||
| @@ -2140,14 +2140,6 @@ See Info node `(elisp)Computed Advice' for detailed documentation." | |||
| 2140 | "Take a macro function DEFINITION and make a lambda out of it." | 2140 | "Take a macro function DEFINITION and make a lambda out of it." |
| 2141 | `(cdr ,definition)) | 2141 | `(cdr ,definition)) |
| 2142 | 2142 | ||
| 2143 | (defmacro ad-subr-p (definition) | ||
| 2144 | ;;"non-nil if DEFINITION is a subr." | ||
| 2145 | (list 'subrp definition)) | ||
| 2146 | |||
| 2147 | (defmacro ad-macro-p (definition) | ||
| 2148 | ;;"non-nil if DEFINITION is a macro." | ||
| 2149 | `(eq (car-safe ,definition) 'macro)) | ||
| 2150 | |||
| 2151 | (defmacro ad-lambda-p (definition) | 2143 | (defmacro ad-lambda-p (definition) |
| 2152 | ;;"non-nil if DEFINITION is a lambda expression." | 2144 | ;;"non-nil if DEFINITION is a lambda expression." |
| 2153 | `(eq (car-safe ,definition) 'lambda)) | 2145 | `(eq (car-safe ,definition) 'lambda)) |
| @@ -2160,12 +2152,12 @@ See Info node `(elisp)Computed Advice' for detailed documentation." | |||
| 2160 | (defmacro ad-compiled-p (definition) | 2152 | (defmacro ad-compiled-p (definition) |
| 2161 | "Return non-nil if DEFINITION is a compiled byte-code object." | 2153 | "Return non-nil if DEFINITION is a compiled byte-code object." |
| 2162 | `(or (byte-code-function-p ,definition) | 2154 | `(or (byte-code-function-p ,definition) |
| 2163 | (and (ad-macro-p ,definition) | 2155 | (and (macrop ,definition) |
| 2164 | (byte-code-function-p (ad-lambdafy ,definition))))) | 2156 | (byte-code-function-p (ad-lambdafy ,definition))))) |
| 2165 | 2157 | ||
| 2166 | (defmacro ad-compiled-code (compiled-definition) | 2158 | (defmacro ad-compiled-code (compiled-definition) |
| 2167 | "Return the byte-code object of a COMPILED-DEFINITION." | 2159 | "Return the byte-code object of a COMPILED-DEFINITION." |
| 2168 | `(if (ad-macro-p ,compiled-definition) | 2160 | `(if (macrop ,compiled-definition) |
| 2169 | (ad-lambdafy ,compiled-definition) | 2161 | (ad-lambdafy ,compiled-definition) |
| 2170 | ,compiled-definition)) | 2162 | ,compiled-definition)) |
| 2171 | 2163 | ||
| @@ -2173,7 +2165,7 @@ See Info node `(elisp)Computed Advice' for detailed documentation." | |||
| 2173 | "Return the lambda expression of a function/macro/advice DEFINITION." | 2165 | "Return the lambda expression of a function/macro/advice DEFINITION." |
| 2174 | (cond ((ad-lambda-p definition) | 2166 | (cond ((ad-lambda-p definition) |
| 2175 | definition) | 2167 | definition) |
| 2176 | ((ad-macro-p definition) | 2168 | ((macrop definition) |
| 2177 | (ad-lambdafy definition)) | 2169 | (ad-lambdafy definition)) |
| 2178 | ((ad-advice-p definition) | 2170 | ((ad-advice-p definition) |
| 2179 | (cdr definition)) | 2171 | (cdr definition)) |
| @@ -2183,7 +2175,7 @@ See Info node `(elisp)Computed Advice' for detailed documentation." | |||
| 2183 | "Return the argument list of DEFINITION." | 2175 | "Return the argument list of DEFINITION." |
| 2184 | (require 'help-fns) | 2176 | (require 'help-fns) |
| 2185 | (help-function-arglist | 2177 | (help-function-arglist |
| 2186 | (if (or (ad-macro-p definition) (ad-advice-p definition)) | 2178 | (if (or (macrop definition) (ad-advice-p definition)) |
| 2187 | (cdr definition) | 2179 | (cdr definition) |
| 2188 | definition) | 2180 | definition) |
| 2189 | 'preserve-names)) | 2181 | 'preserve-names)) |
| @@ -2229,7 +2221,7 @@ definition (see the code for `documentation')." | |||
| 2229 | (defun ad-advised-definition-p (definition) | 2221 | (defun ad-advised-definition-p (definition) |
| 2230 | "Return non-nil if DEFINITION was generated from advice information." | 2222 | "Return non-nil if DEFINITION was generated from advice information." |
| 2231 | (if (or (ad-lambda-p definition) | 2223 | (if (or (ad-lambda-p definition) |
| 2232 | (ad-macro-p definition) | 2224 | (macrop definition) |
| 2233 | (ad-compiled-p definition)) | 2225 | (ad-compiled-p definition)) |
| 2234 | (let ((docstring (ad-docstring definition))) | 2226 | (let ((docstring (ad-docstring definition))) |
| 2235 | (and (stringp docstring) | 2227 | (and (stringp docstring) |
| @@ -2242,8 +2234,8 @@ definition (see the code for `documentation')." | |||
| 2242 | ;; representations, so cache entries preactivated with version | 2234 | ;; representations, so cache entries preactivated with version |
| 2243 | ;; 1 can't be used. | 2235 | ;; 1 can't be used. |
| 2244 | (cond | 2236 | (cond |
| 2245 | ((ad-macro-p definition) 'macro2) | 2237 | ((macrop definition) 'macro2) |
| 2246 | ((ad-subr-p definition) 'subr2) | 2238 | ((subrp definition) 'subr2) |
| 2247 | ((or (ad-lambda-p definition) (ad-compiled-p definition)) 'fun2) | 2239 | ((or (ad-lambda-p definition) (ad-compiled-p definition)) 'fun2) |
| 2248 | ((ad-advice-p definition) 'advice2))) ;; FIXME: Can this ever happen? | 2240 | ((ad-advice-p definition) 'advice2))) ;; FIXME: Can this ever happen? |
| 2249 | 2241 | ||
| @@ -2273,7 +2265,7 @@ For that it has to be fbound with a non-autoload definition." | |||
| 2273 | "True if FUNCTION has an interpreted definition that can be compiled." | 2265 | "True if FUNCTION has an interpreted definition that can be compiled." |
| 2274 | (and (ad-has-proper-definition function) | 2266 | (and (ad-has-proper-definition function) |
| 2275 | (or (ad-lambda-p (symbol-function function)) | 2267 | (or (ad-lambda-p (symbol-function function)) |
| 2276 | (ad-macro-p (symbol-function function))) | 2268 | (macrop (symbol-function function))) |
| 2277 | (not (ad-compiled-p (symbol-function function))))) | 2269 | (not (ad-compiled-p (symbol-function function))))) |
| 2278 | 2270 | ||
| 2279 | (defvar warning-suppress-types) ;From warnings.el. | 2271 | (defvar warning-suppress-types) ;From warnings.el. |
| @@ -2902,7 +2894,7 @@ If COMPILE is nil then the result depends on the value of | |||
| 2902 | ((eq ad-default-compilation-action 'never) nil) | 2894 | ((eq ad-default-compilation-action 'never) nil) |
| 2903 | ((eq ad-default-compilation-action 'always) t) | 2895 | ((eq ad-default-compilation-action 'always) t) |
| 2904 | ((eq ad-default-compilation-action 'like-original) | 2896 | ((eq ad-default-compilation-action 'like-original) |
| 2905 | (or (ad-subr-p (ad-get-orig-definition function)) | 2897 | (or (subrp (ad-get-orig-definition function)) |
| 2906 | (ad-compiled-p (ad-get-orig-definition function)))) | 2898 | (ad-compiled-p (ad-get-orig-definition function)))) |
| 2907 | ;; everything else means `maybe': | 2899 | ;; everything else means `maybe': |
| 2908 | (t (featurep 'byte-compile)))) | 2900 | (t (featurep 'byte-compile)))) |
| @@ -3249,7 +3241,7 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...) | |||
| 3249 | `((ad-set-cache | 3241 | `((ad-set-cache |
| 3250 | ',function | 3242 | ',function |
| 3251 | ;; the function will get compiled: | 3243 | ;; the function will get compiled: |
| 3252 | ,(cond ((ad-macro-p (car preactivation)) | 3244 | ,(cond ((macrop (car preactivation)) |
| 3253 | `(ad-macrofy | 3245 | `(ad-macrofy |
| 3254 | (function | 3246 | (function |
| 3255 | ,(ad-lambdafy | 3247 | ,(ad-lambdafy |
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index ae20e5270e1..ac7e5f12a18 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el | |||
| @@ -295,19 +295,6 @@ A lambda list keyword is a symbol that starts with `&'." | |||
| 295 | (eq (selected-window) | 295 | (eq (selected-window) |
| 296 | (next-window (next-window (selected-window)))))) | 296 | (next-window (next-window (selected-window)))))) |
| 297 | 297 | ||
| 298 | (defsubst edebug-lookup-function (object) | ||
| 299 | (while (and (symbolp object) (fboundp object)) | ||
| 300 | (setq object (symbol-function object))) | ||
| 301 | object) | ||
| 302 | |||
| 303 | (defun edebug-macrop (object) | ||
| 304 | "Return the macro named by OBJECT, or nil if it is not a macro." | ||
| 305 | (setq object (edebug-lookup-function object)) | ||
| 306 | (if (and (listp object) | ||
| 307 | (eq 'macro (car object)) | ||
| 308 | (functionp (cdr object))) | ||
| 309 | object)) | ||
| 310 | |||
| 311 | (defun edebug-sort-alist (alist function) | 298 | (defun edebug-sort-alist (alist function) |
| 312 | ;; Return the ALIST sorted with comparison function FUNCTION. | 299 | ;; Return the ALIST sorted with comparison function FUNCTION. |
| 313 | ;; This uses 'sort so the sorting is destructive. | 300 | ;; This uses 'sort so the sorting is destructive. |
| @@ -1416,7 +1403,7 @@ expressions; a `progn' form will be returned enclosing these forms." | |||
| 1416 | ; but leave it in for compatibility. | 1403 | ; but leave it in for compatibility. |
| 1417 | )) | 1404 | )) |
| 1418 | ;; No edebug-form-spec provided. | 1405 | ;; No edebug-form-spec provided. |
| 1419 | ((edebug-macrop head) | 1406 | ((macrop head) |
| 1420 | (if edebug-eval-macro-args | 1407 | (if edebug-eval-macro-args |
| 1421 | (edebug-forms cursor) | 1408 | (edebug-forms cursor) |
| 1422 | (edebug-sexps cursor))) | 1409 | (edebug-sexps cursor))) |
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index 660eb0365ae..576e72088e9 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el | |||
| @@ -314,9 +314,8 @@ of the piece of advice." | |||
| 314 | ((special-form-p def) | 314 | ((special-form-p def) |
| 315 | ;; Not worth the trouble trying to handle this, I think. | 315 | ;; Not worth the trouble trying to handle this, I think. |
| 316 | (error "Advice impossible: %S is a special form" symbol)) | 316 | (error "Advice impossible: %S is a special form" symbol)) |
| 317 | ((and (symbolp def) | 317 | ((and (symbolp def) (macrop def)) |
| 318 | (eq 'macro (car-safe (ignore-errors (indirect-function def))))) | 318 | (let ((newval `(macro . ,(lambda (&rest r) (macroexpand `(,def . ,r)))))) |
| 319 | (let ((newval (cons 'macro (cdr (indirect-function def))))) | ||
| 320 | (put symbol 'advice--saved-rewrite (cons def (cdr newval))) | 319 | (put symbol 'advice--saved-rewrite (cons def (cdr newval))) |
| 321 | newval)) | 320 | newval)) |
| 322 | ;; `f' might be a pure (hence read-only) cons! | 321 | ;; `f' might be a pure (hence read-only) cons! |
| @@ -351,19 +350,7 @@ of the piece of advice." | |||
| 351 | (when (get symbol 'advice--saved-rewrite) | 350 | (when (get symbol 'advice--saved-rewrite) |
| 352 | (put symbol 'advice--saved-rewrite nil)) | 351 | (put symbol 'advice--saved-rewrite nil)) |
| 353 | (setq newdef (advice--normalize symbol newdef)) | 352 | (setq newdef (advice--normalize symbol newdef)) |
| 354 | (let* ((olddef (advice--strip-macro (symbol-function symbol))) | 353 | (let ((oldadv (advice--symbol-function symbol))) |
| 355 | (oldadv | ||
| 356 | (cond | ||
| 357 | ((null (get symbol 'advice--pending)) | ||
| 358 | (or olddef | ||
| 359 | (progn | ||
| 360 | (message "Delayed advice activation failed for %s: no data" | ||
| 361 | symbol) | ||
| 362 | nil))) | ||
| 363 | ((or (not olddef) (autoloadp olddef)) | ||
| 364 | (get symbol 'advice--pending)) | ||
| 365 | (t (message "Dropping left-over advice--pending for %s" symbol) | ||
| 366 | olddef)))) | ||
| 367 | (if (and newdef (not (autoloadp newdef))) | 354 | (if (and newdef (not (autoloadp newdef))) |
| 368 | (let* ((snewdef (advice--strip-macro newdef)) | 355 | (let* ((snewdef (advice--strip-macro newdef)) |
| 369 | (snewadv (advice--subst-main oldadv snewdef))) | 356 | (snewadv (advice--subst-main oldadv snewdef))) |
| @@ -383,7 +370,6 @@ is defined as a macro, alias, command, ..." | |||
| 383 | ;; TODO: | 370 | ;; TODO: |
| 384 | ;; - record the advice location, to display in describe-function. | 371 | ;; - record the advice location, to display in describe-function. |
| 385 | ;; - change all defadvice in lisp/**/*.el. | 372 | ;; - change all defadvice in lisp/**/*.el. |
| 386 | ;; - rewrite advice.el on top of this. | ||
| 387 | ;; - obsolete advice.el. | 373 | ;; - obsolete advice.el. |
| 388 | (let* ((f (symbol-function symbol)) | 374 | (let* ((f (symbol-function symbol)) |
| 389 | (nf (advice--normalize symbol f))) | 375 | (nf (advice--normalize symbol f))) |
| @@ -420,8 +406,7 @@ of the piece of advice." | |||
| 420 | ((eq (car-safe f) 'macro) (cdr f)) | 406 | ((eq (car-safe f) 'macro) (cdr f)) |
| 421 | (t (symbol-function symbol))) | 407 | (t (symbol-function symbol))) |
| 422 | function) | 408 | function) |
| 423 | (unless (advice--p | 409 | (unless (advice--p (advice--symbol-function symbol)) |
| 424 | (if (eq (car-safe f) 'macro) (cdr f) (symbol-function symbol))) | ||
| 425 | ;; Not advised any more. | 410 | ;; Not advised any more. |
| 426 | (remove-function (get symbol 'defalias-fset-function) | 411 | (remove-function (get symbol 'defalias-fset-function) |
| 427 | #'advice--defalias-fset) | 412 | #'advice--defalias-fset) |
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 50c92518b02..eb2c7f002e8 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el | |||
| @@ -353,23 +353,34 @@ MATCH is the pattern that needs to be matched, of the form: | |||
| 353 | (symbolp . numberp) | 353 | (symbolp . numberp) |
| 354 | (symbolp . consp) | 354 | (symbolp . consp) |
| 355 | (symbolp . arrayp) | 355 | (symbolp . arrayp) |
| 356 | (symbolp . vectorp) | ||
| 356 | (symbolp . stringp) | 357 | (symbolp . stringp) |
| 357 | (symbolp . byte-code-function-p) | 358 | (symbolp . byte-code-function-p) |
| 358 | (integerp . consp) | 359 | (integerp . consp) |
| 359 | (integerp . arrayp) | 360 | (integerp . arrayp) |
| 361 | (integerp . vectorp) | ||
| 360 | (integerp . stringp) | 362 | (integerp . stringp) |
| 361 | (integerp . byte-code-function-p) | 363 | (integerp . byte-code-function-p) |
| 362 | (numberp . consp) | 364 | (numberp . consp) |
| 363 | (numberp . arrayp) | 365 | (numberp . arrayp) |
| 366 | (numberp . vectorp) | ||
| 364 | (numberp . stringp) | 367 | (numberp . stringp) |
| 365 | (numberp . byte-code-function-p) | 368 | (numberp . byte-code-function-p) |
| 366 | (consp . arrayp) | 369 | (consp . arrayp) |
| 370 | (consp . vectorp) | ||
| 367 | (consp . stringp) | 371 | (consp . stringp) |
| 368 | (consp . byte-code-function-p) | 372 | (consp . byte-code-function-p) |
| 369 | (arrayp . stringp) | ||
| 370 | (arrayp . byte-code-function-p) | 373 | (arrayp . byte-code-function-p) |
| 374 | (vectorp . byte-code-function-p) | ||
| 375 | (stringp . vectorp) | ||
| 371 | (stringp . byte-code-function-p))) | 376 | (stringp . byte-code-function-p))) |
| 372 | 377 | ||
| 378 | (defun pcase--mutually-exclusive-p (pred1 pred2) | ||
| 379 | (or (member (cons pred1 pred2) | ||
| 380 | pcase-mutually-exclusive-predicates) | ||
| 381 | (member (cons pred2 pred1) | ||
| 382 | pcase-mutually-exclusive-predicates))) | ||
| 383 | |||
| 373 | (defun pcase--split-match (sym splitter match) | 384 | (defun pcase--split-match (sym splitter match) |
| 374 | (cond | 385 | (cond |
| 375 | ((eq (car match) 'match) | 386 | ((eq (car match) 'match) |
| @@ -433,10 +444,7 @@ MATCH is the pattern that needs to be matched, of the form: | |||
| 433 | ;; A QPattern but not for a cons, can only go to the `else' side. | 444 | ;; A QPattern but not for a cons, can only go to the `else' side. |
| 434 | ((eq (car-safe pat) '\`) '(:pcase--fail . nil)) | 445 | ((eq (car-safe pat) '\`) '(:pcase--fail . nil)) |
| 435 | ((and (eq (car-safe pat) 'pred) | 446 | ((and (eq (car-safe pat) 'pred) |
| 436 | (or (member (cons 'consp (cadr pat)) | 447 | (pcase--mutually-exclusive-p #'consp (cadr pat))) |
| 437 | pcase-mutually-exclusive-predicates) | ||
| 438 | (member (cons (cadr pat) 'consp) | ||
| 439 | pcase-mutually-exclusive-predicates))) | ||
| 440 | '(:pcase--fail . nil)))) | 448 | '(:pcase--fail . nil)))) |
| 441 | 449 | ||
| 442 | (defun pcase--split-equal (elem pat) | 450 | (defun pcase--split-equal (elem pat) |
| @@ -496,11 +504,14 @@ MATCH is the pattern that needs to be matched, of the form: | |||
| 496 | (not (pcase--fgrep (mapcar #'car vars) (cadr upat))))) | 504 | (not (pcase--fgrep (mapcar #'car vars) (cadr upat))))) |
| 497 | '(:pcase--succeed . :pcase--fail)) | 505 | '(:pcase--succeed . :pcase--fail)) |
| 498 | ((and (eq 'pred (car upat)) | 506 | ((and (eq 'pred (car upat)) |
| 499 | (eq 'pred (car-safe pat)) | 507 | (let ((otherpred |
| 500 | (or (member (cons (cadr upat) (cadr pat)) | 508 | (cond ((eq 'pred (car-safe pat)) (cadr pat)) |
| 501 | pcase-mutually-exclusive-predicates) | 509 | ((not (eq '\` (car-safe pat))) nil) |
| 502 | (member (cons (cadr pat) (cadr upat)) | 510 | ((consp (cadr pat)) #'consp) |
| 503 | pcase-mutually-exclusive-predicates))) | 511 | ((vectorp (cadr pat)) #'vectorp) |
| 512 | ((byte-code-function-p (cadr pat)) | ||
| 513 | #'byte-code-function-p)))) | ||
| 514 | (pcase--mutually-exclusive-p (cadr upat) otherpred))) | ||
| 504 | '(:pcase--fail . nil)) | 515 | '(:pcase--fail . nil)) |
| 505 | ((and (eq 'pred (car upat)) | 516 | ((and (eq 'pred (car upat)) |
| 506 | (eq '\` (car-safe pat)) | 517 | (eq '\` (car-safe pat)) |
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 69dc6c76b41..ef8a53f3c0b 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el | |||
| @@ -993,14 +993,6 @@ at the moment are: | |||
| 993 | ,@commands | 993 | ,@commands |
| 994 | (eshell-debug-command ,(concat "done " (eval tag)) form)))) | 994 | (eshell-debug-command ,(concat "done " (eval tag)) form)))) |
| 995 | 995 | ||
| 996 | (defsubst eshell-macrop (object) | ||
| 997 | "Return t if OBJECT is a macro or nil otherwise." | ||
| 998 | (and (symbolp object) (fboundp object) | ||
| 999 | (setq object (indirect-function object)) | ||
| 1000 | (listp object) | ||
| 1001 | (eq 'macro (car object)) | ||
| 1002 | (functionp (cdr object)))) | ||
| 1003 | |||
| 1004 | (defun eshell-do-eval (form &optional synchronous-p) | 996 | (defun eshell-do-eval (form &optional synchronous-p) |
| 1005 | "Evaluate form, simplifying it as we go. | 997 | "Evaluate form, simplifying it as we go. |
| 1006 | Unless SYNCHRONOUS-P is non-nil, throws `eshell-defer' if it needs to | 998 | Unless SYNCHRONOUS-P is non-nil, throws `eshell-defer' if it needs to |
| @@ -1016,7 +1008,7 @@ be finished later after the completion of an asynchronous subprocess." | |||
| 1016 | (setq form (cadr (cadr form)))) | 1008 | (setq form (cadr (cadr form)))) |
| 1017 | ;; expand any macros directly into the form. This is done so that | 1009 | ;; expand any macros directly into the form. This is done so that |
| 1018 | ;; we can modify any `let' forms to evaluate only once. | 1010 | ;; we can modify any `let' forms to evaluate only once. |
| 1019 | (if (eshell-macrop (car form)) | 1011 | (if (macrop (car form)) |
| 1020 | (let ((exp (eshell-copy-tree (macroexpand form)))) | 1012 | (let ((exp (eshell-copy-tree (macroexpand form)))) |
| 1021 | (eshell-manipulate (format "expanding macro `%s'" | 1013 | (eshell-manipulate (format "expanding macro `%s'" |
| 1022 | (symbol-name (car form))) | 1014 | (symbol-name (car form))) |
diff --git a/lisp/subr.el b/lisp/subr.el index 3b85a9bedb0..bdeee677471 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -2750,6 +2750,13 @@ Otherwise, return nil." | |||
| 2750 | (setq object (indirect-function object t))) | 2750 | (setq object (indirect-function object t))) |
| 2751 | (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled))) | 2751 | (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled))) |
| 2752 | 2752 | ||
| 2753 | (defun macrop (object) | ||
| 2754 | "Non-nil if and only if OBJECT is a macro." | ||
| 2755 | (let ((def (indirect-function object t))) | ||
| 2756 | (when (consp def) | ||
| 2757 | (or (eq 'macro (car def)) | ||
| 2758 | (and (eq 'autoload (car def)) (memq (nth 4 def) '(macro t))))))) | ||
| 2759 | |||
| 2753 | (defun field-at-pos (pos) | 2760 | (defun field-at-pos (pos) |
| 2754 | "Return the field at position POS, taking stickiness etc into account." | 2761 | "Return the field at position POS, taking stickiness etc into account." |
| 2755 | (let ((raw-field (get-char-property (field-beginning pos) 'field))) | 2762 | (let ((raw-field (get-char-property (field-beginning pos) 'field))) |
| @@ -4050,10 +4057,14 @@ backwards ARG times if negative." | |||
| 4050 | 4057 | ||
| 4051 | ;;;; Text clones | 4058 | ;;;; Text clones |
| 4052 | 4059 | ||
| 4053 | (defun text-clone-maintain (ol1 after beg end &optional _len) | 4060 | (defvar text-clone--maintaining nil) |
| 4061 | |||
| 4062 | (defun text-clone--maintain (ol1 after beg end &optional _len) | ||
| 4054 | "Propagate the changes made under the overlay OL1 to the other clones. | 4063 | "Propagate the changes made under the overlay OL1 to the other clones. |
| 4055 | This is used on the `modification-hooks' property of text clones." | 4064 | This is used on the `modification-hooks' property of text clones." |
| 4056 | (when (and after (not undo-in-progress) (overlay-start ol1)) | 4065 | (when (and after (not undo-in-progress) |
| 4066 | (not text-clone--maintaining) | ||
| 4067 | (overlay-start ol1)) | ||
| 4057 | (let ((margin (if (overlay-get ol1 'text-clone-spreadp) 1 0))) | 4068 | (let ((margin (if (overlay-get ol1 'text-clone-spreadp) 1 0))) |
| 4058 | (setq beg (max beg (+ (overlay-start ol1) margin))) | 4069 | (setq beg (max beg (+ (overlay-start ol1) margin))) |
| 4059 | (setq end (min end (- (overlay-end ol1) margin))) | 4070 | (setq end (min end (- (overlay-end ol1) margin))) |
| @@ -4084,7 +4095,7 @@ This is used on the `modification-hooks' property of text clones." | |||
| 4084 | (tail (- (overlay-end ol1) end)) | 4095 | (tail (- (overlay-end ol1) end)) |
| 4085 | (str (buffer-substring beg end)) | 4096 | (str (buffer-substring beg end)) |
| 4086 | (nothing-left t) | 4097 | (nothing-left t) |
| 4087 | (inhibit-modification-hooks t)) | 4098 | (text-clone--maintaining t)) |
| 4088 | (dolist (ol2 (overlay-get ol1 'text-clones)) | 4099 | (dolist (ol2 (overlay-get ol1 'text-clones)) |
| 4089 | (let ((oe (overlay-end ol2))) | 4100 | (let ((oe (overlay-end ol2))) |
| 4090 | (unless (or (eq ol1 ol2) (null oe)) | 4101 | (unless (or (eq ol1 ol2) (null oe)) |
| @@ -4095,7 +4106,7 @@ This is used on the `modification-hooks' property of text clones." | |||
| 4095 | (unless (> mod-beg (point)) | 4106 | (unless (> mod-beg (point)) |
| 4096 | (save-excursion (insert str)) | 4107 | (save-excursion (insert str)) |
| 4097 | (delete-region mod-beg (point))) | 4108 | (delete-region mod-beg (point))) |
| 4098 | ;;(overlay-put ol2 'modification-hooks '(text-clone-maintain)) | 4109 | ;;(overlay-put ol2 'modification-hooks '(text-clone--maintain)) |
| 4099 | )))) | 4110 | )))) |
| 4100 | (if nothing-left (delete-overlay ol1)))))))) | 4111 | (if nothing-left (delete-overlay ol1)))))))) |
| 4101 | 4112 | ||
| @@ -4126,17 +4137,18 @@ clone should be incorporated in the clone." | |||
| 4126 | (>= pt-end (point-max)) | 4137 | (>= pt-end (point-max)) |
| 4127 | (>= start (point-max))) | 4138 | (>= start (point-max))) |
| 4128 | 0 1)) | 4139 | 0 1)) |
| 4140 | ;; FIXME: Reuse overlays at point to extend dups! | ||
| 4129 | (ol1 (make-overlay (- start start-margin) (+ end end-margin) nil t)) | 4141 | (ol1 (make-overlay (- start start-margin) (+ end end-margin) nil t)) |
| 4130 | (ol2 (make-overlay (- (point) start-margin) (+ pt-end end-margin) nil t)) | 4142 | (ol2 (make-overlay (- (point) start-margin) (+ pt-end end-margin) nil t)) |
| 4131 | (dups (list ol1 ol2))) | 4143 | (dups (list ol1 ol2))) |
| 4132 | (overlay-put ol1 'modification-hooks '(text-clone-maintain)) | 4144 | (overlay-put ol1 'modification-hooks '(text-clone--maintain)) |
| 4133 | (when spreadp (overlay-put ol1 'text-clone-spreadp t)) | 4145 | (when spreadp (overlay-put ol1 'text-clone-spreadp t)) |
| 4134 | (when syntax (overlay-put ol1 'text-clone-syntax syntax)) | 4146 | (when syntax (overlay-put ol1 'text-clone-syntax syntax)) |
| 4135 | ;;(overlay-put ol1 'face 'underline) | 4147 | ;;(overlay-put ol1 'face 'underline) |
| 4136 | (overlay-put ol1 'evaporate t) | 4148 | (overlay-put ol1 'evaporate t) |
| 4137 | (overlay-put ol1 'text-clones dups) | 4149 | (overlay-put ol1 'text-clones dups) |
| 4138 | ;; | 4150 | ;; |
| 4139 | (overlay-put ol2 'modification-hooks '(text-clone-maintain)) | 4151 | (overlay-put ol2 'modification-hooks '(text-clone--maintain)) |
| 4140 | (when spreadp (overlay-put ol2 'text-clone-spreadp t)) | 4152 | (when spreadp (overlay-put ol2 'text-clone-spreadp t)) |
| 4141 | (when syntax (overlay-put ol2 'text-clone-syntax syntax)) | 4153 | (when syntax (overlay-put ol2 'text-clone-syntax syntax)) |
| 4142 | ;;(overlay-put ol2 'face 'underline) | 4154 | ;;(overlay-put ol2 'face 'underline) |