aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleh Krehel2015-05-19 09:49:12 +0200
committerOleh Krehel2015-05-20 15:20:37 +0200
commit5d752c8a1c28e003ded0f2daa0d93eb12a31195a (patch)
tree51afc7bcc5a4374141c52f1390f04c199091f3a0
parent1972e49f924dc8706aef512a0d69fd7c29a4f1f6 (diff)
downloademacs-5d752c8a1c28e003ded0f2daa0d93eb12a31195a.tar.gz
emacs-5d752c8a1c28e003ded0f2daa0d93eb12a31195a.zip
Add let-when-compile macro instead of using pcase-let
* lisp/subr.el (let-when-compile): New let-like macro that makes its bindings known to macros like `eval-when-compile' in the body. * lisp/emacs-lisp/lisp-mode.el: Change the top-level `pcase-let' to a `let-when-compile'. Also comment out the unused lexical var `el-kws-re'. The change greatly improves readability, while providing almost the same (even shorter) byte code: instead of pre-evaluating 10 variables, tossing them into a list, and destructuring that list a full screen page later, the variables are simply bound as they are evaluated, wrapped individually in `eval-when-compile'.
-rw-r--r--lisp/emacs-lisp/lisp-mode.el482
-rw-r--r--lisp/subr.el13
2 files changed, 253 insertions, 242 deletions
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 108d5ccb0e3..6facf576055 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -229,248 +229,246 @@
229 (match-beginning 0))))) 229 (match-beginning 0)))))
230 (throw 'found t)))))) 230 (throw 'found t))))))
231 231
232(pcase-let 232(let-when-compile
233 ((`(,vdefs ,tdefs 233 ((lisp-fdefs '("defmacro" "defsubst" "defun"))
234 ,el-defs-re ,cl-defs-re 234 (lisp-vdefs '("defvar"))
235 ,el-kws-re ,cl-kws-re 235 (lisp-kw '("cond" "if" "while" "let" "let*" "progn" "prog1"
236 ,el-errs-re ,cl-errs-re) 236 "prog2" "lambda" "unwind-protect" "condition-case"
237 (eval-when-compile 237 "when" "unless" "with-output-to-string"
238 (let ((lisp-fdefs '("defmacro" "defsubst" "defun")) 238 "ignore-errors" "dotimes" "dolist" "declare"))
239 (lisp-vdefs '("defvar")) 239 (lisp-errs '("warn" "error" "signal"))
240 (lisp-kw '("cond" "if" "while" "let" "let*" "progn" "prog1" 240 ;; Elisp constructs. Now they are update dynamically
241 "prog2" "lambda" "unwind-protect" "condition-case" 241 ;; from obarray but they are also used for setting up
242 "when" "unless" "with-output-to-string" 242 ;; the keywords for Common Lisp.
243 "ignore-errors" "dotimes" "dolist" "declare")) 243 (el-fdefs '("define-advice" "defadvice" "defalias"
244 (lisp-errs '("warn" "error" "signal")) 244 "define-derived-mode" "define-minor-mode"
245 ;; Elisp constructs. Now they are update dynamically 245 "define-generic-mode" "define-global-minor-mode"
246 ;; from obarray but they are also used for setting up 246 "define-globalized-minor-mode" "define-skeleton"
247 ;; the keywords for Common Lisp. 247 "define-widget"))
248 (el-fdefs '("define-advice" "defadvice" "defalias" 248 (el-vdefs '("defconst" "defcustom" "defvaralias" "defvar-local"
249 "define-derived-mode" "define-minor-mode" 249 "defface"))
250 "define-generic-mode" "define-global-minor-mode" 250 (el-tdefs '("defgroup" "deftheme"))
251 "define-globalized-minor-mode" "define-skeleton" 251 (el-kw '("while-no-input" "letrec" "pcase" "pcase-exhaustive"
252 "define-widget")) 252 "pcase-lambda" "pcase-let" "pcase-let*" "save-restriction"
253 (el-vdefs '("defconst" "defcustom" "defvaralias" "defvar-local" 253 "save-excursion" "save-selected-window"
254 "defface")) 254 ;; "eval-after-load" "eval-next-after-load"
255 (el-tdefs '("defgroup" "deftheme")) 255 "save-window-excursion" "save-current-buffer"
256 (el-kw '("while-no-input" "letrec" "pcase" "pcase-exhaustive" 256 "save-match-data" "combine-after-change-calls"
257 "pcase-lambda" "pcase-let" "pcase-let*" "save-restriction" 257 "condition-case-unless-debug" "track-mouse"
258 "save-excursion" "save-selected-window" 258 "eval-and-compile" "eval-when-compile" "with-case-table"
259 ;; "eval-after-load" "eval-next-after-load" 259 "with-category-table" "with-coding-priority"
260 "save-window-excursion" "save-current-buffer" 260 "with-current-buffer" "with-demoted-errors"
261 "save-match-data" "combine-after-change-calls" 261 "with-electric-help" "with-eval-after-load"
262 "condition-case-unless-debug" "track-mouse" 262 "with-file-modes"
263 "eval-and-compile" "eval-when-compile" "with-case-table" 263 "with-local-quit" "with-no-warnings"
264 "with-category-table" "with-coding-priority" 264 "with-output-to-temp-buffer" "with-selected-window"
265 "with-current-buffer" "with-demoted-errors" 265 "with-selected-frame" "with-silent-modifications"
266 "with-electric-help" "with-eval-after-load" 266 "with-syntax-table" "with-temp-buffer" "with-temp-file"
267 "with-file-modes" 267 "with-temp-message" "with-timeout"
268 "with-local-quit" "with-no-warnings" 268 "with-timeout-handler"))
269 "with-output-to-temp-buffer" "with-selected-window" 269 (el-errs '("user-error"))
270 "with-selected-frame" "with-silent-modifications" 270 ;; Common-Lisp constructs supported by EIEIO. FIXME: namespace.
271 "with-syntax-table" "with-temp-buffer" "with-temp-file" 271 (eieio-fdefs '("defgeneric" "defmethod"))
272 "with-temp-message" "with-timeout" 272 (eieio-tdefs '("defclass"))
273 "with-timeout-handler")) 273 (eieio-kw '("with-slots"))
274 (el-errs '("user-error")) 274 ;; Common-Lisp constructs supported by cl-lib.
275 ;; Common-Lisp constructs supported by EIEIO. FIXME: namespace. 275 (cl-lib-fdefs '("defmacro" "defsubst" "defun" "defmethod"))
276 (eieio-fdefs '("defgeneric" "defmethod")) 276 (cl-lib-tdefs '("defstruct" "deftype"))
277 (eieio-tdefs '("defclass")) 277 (cl-lib-kw '("progv" "eval-when" "case" "ecase" "typecase"
278 (eieio-kw '("with-slots")) 278 "etypecase" "ccase" "ctypecase" "loop" "do" "do*"
279 ;; Common-Lisp constructs supported by cl-lib. 279 "the" "locally" "proclaim" "declaim" "letf" "go"
280 (cl-lib-fdefs '("defmacro" "defsubst" "defun" "defmethod")) 280 ;; "lexical-let" "lexical-let*"
281 (cl-lib-tdefs '("defstruct" "deftype")) 281 "symbol-macrolet" "flet" "flet*" "destructuring-bind"
282 (cl-lib-kw '("progv" "eval-when" "case" "ecase" "typecase" 282 "labels" "macrolet" "tagbody" "multiple-value-bind"
283 "etypecase" "ccase" "ctypecase" "loop" "do" "do*" 283 "block" "return" "return-from"))
284 "the" "locally" "proclaim" "declaim" "letf" "go" 284 (cl-lib-errs '("assert" "check-type"))
285 ;; "lexical-let" "lexical-let*" 285 ;; Common-Lisp constructs not supported by cl-lib.
286 "symbol-macrolet" "flet" "flet*" "destructuring-bind" 286 (cl-fdefs '("defsetf" "define-method-combination"
287 "labels" "macrolet" "tagbody" "multiple-value-bind" 287 "define-condition" "define-setf-expander"
288 "block" "return" "return-from")) 288 ;; "define-function"??
289 (cl-lib-errs '("assert" "check-type")) 289 "define-compiler-macro" "define-modify-macro"))
290 ;; Common-Lisp constructs not supported by cl-lib. 290 (cl-vdefs '("define-symbol-macro" "defconstant" "defparameter"))
291 (cl-fdefs '("defsetf" "define-method-combination" 291 (cl-tdefs '("defpackage" "defstruct" "deftype"))
292 "define-condition" "define-setf-expander" 292 (cl-kw '("prog" "prog*" "handler-case" "handler-bind"
293 ;; "define-function"?? 293 "in-package" "restart-case" ;; "inline"
294 "define-compiler-macro" "define-modify-macro")) 294 "restart-bind" "break" "multiple-value-prog1"
295 (cl-vdefs '("define-symbol-macro" "defconstant" "defparameter")) 295 "compiler-let" "with-accessors" "with-compilation-unit"
296 (cl-tdefs '("defpackage" "defstruct" "deftype")) 296 "with-condition-restarts" "with-hash-table-iterator"
297 (cl-kw '("prog" "prog*" "handler-case" "handler-bind" 297 "with-input-from-string" "with-open-file"
298 "in-package" "restart-case" ;; "inline" 298 "with-open-stream" "with-package-iterator"
299 "restart-bind" "break" "multiple-value-prog1" 299 "with-simple-restart" "with-standard-io-syntax"))
300 "compiler-let" "with-accessors" "with-compilation-unit" 300 (cl-errs '("abort" "cerror")))
301 "with-condition-restarts" "with-hash-table-iterator" 301 (let ((vdefs (eval-when-compile
302 "with-input-from-string" "with-open-file" 302 (append lisp-vdefs el-vdefs cl-vdefs)))
303 "with-open-stream" "with-package-iterator" 303 (tdefs (eval-when-compile
304 "with-simple-restart" "with-standard-io-syntax")) 304 (append el-tdefs eieio-tdefs cl-tdefs cl-lib-tdefs
305 (cl-errs '("abort" "cerror"))) 305 (mapcar (lambda (s) (concat "cl-" s)) cl-lib-tdefs))))
306 306 ;; Elisp and Common Lisp definers.
307 (list (append lisp-vdefs el-vdefs cl-vdefs) 307 (el-defs-re (eval-when-compile
308 (append el-tdefs eieio-tdefs cl-tdefs cl-lib-tdefs 308 (regexp-opt (append lisp-fdefs lisp-vdefs
309 (mapcar (lambda (s) (concat "cl-" s)) cl-lib-tdefs)) 309 el-fdefs el-vdefs el-tdefs
310 310 (mapcar (lambda (s) (concat "cl-" s))
311 ;; Elisp and Common Lisp definers. 311 (append cl-lib-fdefs cl-lib-tdefs))
312 (regexp-opt (append lisp-fdefs lisp-vdefs 312 eieio-fdefs eieio-tdefs)
313 el-fdefs el-vdefs el-tdefs 313 t)))
314 (mapcar (lambda (s) (concat "cl-" s)) 314 (cl-defs-re (eval-when-compile
315 (append cl-lib-fdefs cl-lib-tdefs)) 315 (regexp-opt (append lisp-fdefs lisp-vdefs
316 eieio-fdefs eieio-tdefs) 316 cl-lib-fdefs cl-lib-tdefs
317 t) 317 eieio-fdefs eieio-tdefs
318 (regexp-opt (append lisp-fdefs lisp-vdefs 318 cl-fdefs cl-vdefs cl-tdefs)
319 cl-lib-fdefs cl-lib-tdefs 319 t)))
320 eieio-fdefs eieio-tdefs 320 ;; Elisp and Common Lisp keywords.
321 cl-fdefs cl-vdefs cl-tdefs) 321 ;; (el-kws-re (eval-when-compile
322 t) 322 ;; (regexp-opt (append
323 323 ;; lisp-kw el-kw eieio-kw
324 ;; Elisp and Common Lisp keywords. 324 ;; (cons "go" (mapcar (lambda (s) (concat "cl-" s))
325 (regexp-opt (append 325 ;; (remove "go" cl-lib-kw))))
326 lisp-kw el-kw eieio-kw 326 ;; t)))
327 (cons "go" (mapcar (lambda (s) (concat "cl-" s)) 327 (cl-kws-re (eval-when-compile
328 (remove "go" cl-lib-kw)))) 328 (regexp-opt (append lisp-kw cl-kw eieio-kw cl-lib-kw)
329 t) 329 t)))
330 (regexp-opt (append lisp-kw cl-kw eieio-kw cl-lib-kw) 330 ;; Elisp and Common Lisp "errors".
331 t) 331 (el-errs-re (eval-when-compile
332 332 (regexp-opt (append (mapcar (lambda (s) (concat "cl-" s))
333 ;; Elisp and Common Lisp "errors". 333 cl-lib-errs)
334 (regexp-opt (append (mapcar (lambda (s) (concat "cl-" s)) 334 lisp-errs el-errs)
335 cl-lib-errs) 335 t)))
336 lisp-errs el-errs) 336 (cl-errs-re (eval-when-compile
337 t) 337 (regexp-opt (append lisp-errs cl-lib-errs cl-errs) t))))
338 (regexp-opt (append lisp-errs cl-lib-errs cl-errs) t)))))) 338 (dolist (v vdefs)
339 339 (put (intern v) 'lisp-define-type 'var))
340 (dolist (v vdefs) 340 (dolist (v tdefs)
341 (put (intern v) 'lisp-define-type 'var)) 341 (put (intern v) 'lisp-define-type 'type))
342 (dolist (v tdefs) 342
343 (put (intern v) 'lisp-define-type 'type)) 343 (define-obsolete-variable-alias 'lisp-font-lock-keywords-1
344 344 'lisp-el-font-lock-keywords-1 "24.4")
345 (define-obsolete-variable-alias 'lisp-font-lock-keywords-1 345 (defconst lisp-el-font-lock-keywords-1
346 'lisp-el-font-lock-keywords-1 "24.4") 346 `( ;; Definitions.
347 (defconst lisp-el-font-lock-keywords-1 347 (,(concat "(" el-defs-re "\\_>"
348 `( ;; Definitions. 348 ;; Any whitespace and defined object.
349 (,(concat "(" el-defs-re "\\_>" 349 "[ \t']*"
350 ;; Any whitespace and defined object. 350 "\\(([ \t']*\\)?" ;; An opening paren.
351 "[ \t']*" 351 "\\(\\(setf\\)[ \t]+\\(?:\\sw\\|\\s_\\)+\\|\\(?:\\sw\\|\\s_\\)+\\)?")
352 "\\(([ \t']*\\)?" ;; An opening paren. 352 (1 font-lock-keyword-face)
353 "\\(\\(setf\\)[ \t]+\\(?:\\sw\\|\\s_\\)+\\|\\(?:\\sw\\|\\s_\\)+\\)?") 353 (3 (let ((type (get (intern-soft (match-string 1)) 'lisp-define-type)))
354 (1 font-lock-keyword-face) 354 (cond ((eq type 'var) font-lock-variable-name-face)
355 (3 (let ((type (get (intern-soft (match-string 1)) 'lisp-define-type))) 355 ((eq type 'type) font-lock-type-face)
356 (cond ((eq type 'var) font-lock-variable-name-face) 356 ;; If match-string 2 is non-nil, we encountered a
357 ((eq type 'type) font-lock-type-face) 357 ;; form like (defalias (intern (concat s "-p"))),
358 ;; If match-string 2 is non-nil, we encountered a 358 ;; unless match-string 4 is also there. Then its a
359 ;; form like (defalias (intern (concat s "-p"))), 359 ;; defmethod with (setf foo) as name.
360 ;; unless match-string 4 is also there. Then its a 360 ((or (not (match-string 2)) ;; Normal defun.
361 ;; defmethod with (setf foo) as name. 361 (and (match-string 2) ;; Setf method.
362 ((or (not (match-string 2)) ;; Normal defun. 362 (match-string 4))) font-lock-function-name-face)))
363 (and (match-string 2) ;; Setf method. 363 nil t))
364 (match-string 4))) font-lock-function-name-face))) 364 ;; Emacs Lisp autoload cookies. Supports the slightly different
365 nil t)) 365 ;; forms used by mh-e, calendar, etc.
366 ;; Emacs Lisp autoload cookies. Supports the slightly different 366 ("^;;;###\\([-a-z]*autoload\\)" 1 font-lock-warning-face prepend))
367 ;; forms used by mh-e, calendar, etc. 367 "Subdued level highlighting for Emacs Lisp mode.")
368 ("^;;;###\\([-a-z]*autoload\\)" 1 font-lock-warning-face prepend)) 368
369 "Subdued level highlighting for Emacs Lisp mode.") 369 (defconst lisp-cl-font-lock-keywords-1
370 370 `( ;; Definitions.
371 (defconst lisp-cl-font-lock-keywords-1 371 (,(concat "(" cl-defs-re "\\_>"
372 `( ;; Definitions. 372 ;; Any whitespace and defined object.
373 (,(concat "(" cl-defs-re "\\_>" 373 "[ \t']*"
374 ;; Any whitespace and defined object. 374 "\\(([ \t']*\\)?" ;; An opening paren.
375 "[ \t']*" 375 "\\(\\(setf\\)[ \t]+\\(?:\\sw\\|\\s_\\)+\\|\\(?:\\sw\\|\\s_\\)+\\)?")
376 "\\(([ \t']*\\)?" ;; An opening paren. 376 (1 font-lock-keyword-face)
377 "\\(\\(setf\\)[ \t]+\\(?:\\sw\\|\\s_\\)+\\|\\(?:\\sw\\|\\s_\\)+\\)?") 377 (3 (let ((type (get (intern-soft (match-string 1)) 'lisp-define-type)))
378 (1 font-lock-keyword-face) 378 (cond ((eq type 'var) font-lock-variable-name-face)
379 (3 (let ((type (get (intern-soft (match-string 1)) 'lisp-define-type))) 379 ((eq type 'type) font-lock-type-face)
380 (cond ((eq type 'var) font-lock-variable-name-face) 380 ((or (not (match-string 2)) ;; Normal defun.
381 ((eq type 'type) font-lock-type-face) 381 (and (match-string 2) ;; Setf function.
382 ((or (not (match-string 2)) ;; Normal defun. 382 (match-string 4))) font-lock-function-name-face)))
383 (and (match-string 2) ;; Setf function. 383 nil t)))
384 (match-string 4))) font-lock-function-name-face))) 384 "Subdued level highlighting for Lisp modes.")
385 nil t))) 385
386 "Subdued level highlighting for Lisp modes.") 386 (define-obsolete-variable-alias 'lisp-font-lock-keywords-2
387 387 'lisp-el-font-lock-keywords-2 "24.4")
388 (define-obsolete-variable-alias 'lisp-font-lock-keywords-2 388 (defconst lisp-el-font-lock-keywords-2
389 'lisp-el-font-lock-keywords-2 "24.4") 389 (append
390 (defconst lisp-el-font-lock-keywords-2 390 lisp-el-font-lock-keywords-1
391 (append 391 `( ;; Regexp negated char group.
392 lisp-el-font-lock-keywords-1 392 ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)
393 `( ;; Regexp negated char group. 393 ;; Control structures. Common Lisp forms.
394 ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend) 394 (lisp--el-match-keyword . 1)
395 ;; Control structures. Common Lisp forms. 395 ;; Exit/Feature symbols as constants.
396 (lisp--el-match-keyword . 1) 396 (,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>"
397 ;; Exit/Feature symbols as constants. 397 "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?")
398 (,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>" 398 (1 font-lock-keyword-face)
399 "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?") 399 (2 font-lock-constant-face nil t))
400 (1 font-lock-keyword-face) 400 ;; Erroneous structures.
401 (2 font-lock-constant-face nil t)) 401 (,(concat "(" el-errs-re "\\_>")
402 ;; Erroneous structures. 402 (1 font-lock-warning-face))
403 (,(concat "(" el-errs-re "\\_>") 403 ;; Words inside \\[] tend to be for `substitute-command-keys'.
404 (1 font-lock-warning-face)) 404 ("\\\\\\\\\\[\\(\\(?:\\sw\\|\\s_\\)+\\)\\]"
405 ;; Words inside \\[] tend to be for `substitute-command-keys'. 405 (1 font-lock-constant-face prepend))
406 ("\\\\\\\\\\[\\(\\(?:\\sw\\|\\s_\\)+\\)\\]" 406 ;; Words inside `' tend to be symbol names.
407 (1 font-lock-constant-face prepend)) 407 ("`\\(\\(?:\\sw\\|\\s_\\)\\(?:\\sw\\|\\s_\\)+\\)'"
408 ;; Words inside `' tend to be symbol names. 408 (1 font-lock-constant-face prepend))
409 ("`\\(\\(?:\\sw\\|\\s_\\)\\(?:\\sw\\|\\s_\\)+\\)'" 409 ;; Constant values.
410 (1 font-lock-constant-face prepend)) 410 ("\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" 0 font-lock-builtin-face)
411 ;; Constant values. 411 ;; ELisp and CLisp `&' keywords as types.
412 ("\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" 0 font-lock-builtin-face) 412 ("\\_<\\&\\(?:\\sw\\|\\s_\\)+\\_>" . font-lock-type-face)
413 ;; ELisp and CLisp `&' keywords as types. 413 ;; ELisp regexp grouping constructs
414 ("\\_<\\&\\(?:\\sw\\|\\s_\\)+\\_>" . font-lock-type-face) 414 (,(lambda (bound)
415 ;; ELisp regexp grouping constructs 415 (catch 'found
416 (,(lambda (bound) 416 ;; The following loop is needed to continue searching after matches
417 (catch 'found 417 ;; that do not occur in strings. The associated regexp matches one
418 ;; The following loop is needed to continue searching after matches 418 ;; of `\\\\' `\\(' `\\(?:' `\\|' `\\)'. `\\\\' has been included to
419 ;; that do not occur in strings. The associated regexp matches one 419 ;; avoid highlighting, for example, `\\(' in `\\\\('.
420 ;; of `\\\\' `\\(' `\\(?:' `\\|' `\\)'. `\\\\' has been included to 420 (while (re-search-forward "\\(\\\\\\\\\\)\\(?:\\(\\\\\\\\\\)\\|\\((\\(?:\\?[0-9]*:\\)?\\|[|)]\\)\\)" bound t)
421 ;; avoid highlighting, for example, `\\(' in `\\\\('. 421 (unless (match-beginning 2)
422 (while (re-search-forward "\\(\\\\\\\\\\)\\(?:\\(\\\\\\\\\\)\\|\\((\\(?:\\?[0-9]*:\\)?\\|[|)]\\)\\)" bound t) 422 (let ((face (get-text-property (1- (point)) 'face)))
423 (unless (match-beginning 2) 423 (when (or (and (listp face)
424 (let ((face (get-text-property (1- (point)) 'face))) 424 (memq 'font-lock-string-face face))
425 (when (or (and (listp face) 425 (eq 'font-lock-string-face face))
426 (memq 'font-lock-string-face face)) 426 (throw 'found t)))))))
427 (eq 'font-lock-string-face face)) 427 (1 'font-lock-regexp-grouping-backslash prepend)
428 (throw 'found t))))))) 428 (3 'font-lock-regexp-grouping-construct prepend))
429 (1 'font-lock-regexp-grouping-backslash prepend) 429 ;; This is too general -- rms.
430 (3 'font-lock-regexp-grouping-construct prepend)) 430 ;; A user complained that he has functions whose names start with `do'
431 ;; This is too general -- rms. 431 ;; and that they get the wrong color.
432 ;; A user complained that he has functions whose names start with `do' 432 ;; ;; CL `with-' and `do-' constructs
433 ;; and that they get the wrong color. 433 ;;("(\\(\\(do-\\|with-\\)\\(\\s_\\|\\w\\)*\\)" 1 font-lock-keyword-face)
434 ;; ;; CL `with-' and `do-' constructs 434 (lisp--match-hidden-arg
435 ;;("(\\(\\(do-\\|with-\\)\\(\\s_\\|\\w\\)*\\)" 1 font-lock-keyword-face) 435 (0 '(face font-lock-warning-face
436 (lisp--match-hidden-arg 436 help-echo "Hidden behind deeper element; move to another line?")))
437 (0 '(face font-lock-warning-face 437 ))
438 help-echo "Hidden behind deeper element; move to another line?"))) 438 "Gaudy level highlighting for Emacs Lisp mode.")
439 )) 439
440 "Gaudy level highlighting for Emacs Lisp mode.") 440 (defconst lisp-cl-font-lock-keywords-2
441 441 (append
442 (defconst lisp-cl-font-lock-keywords-2 442 lisp-cl-font-lock-keywords-1
443 (append 443 `( ;; Regexp negated char group.
444 lisp-cl-font-lock-keywords-1 444 ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)
445 `( ;; Regexp negated char group. 445 ;; Control structures. Common Lisp forms.
446 ("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend) 446 (,(concat "(" cl-kws-re "\\_>") . 1)
447 ;; Control structures. Common Lisp forms. 447 ;; Exit/Feature symbols as constants.
448 (,(concat "(" cl-kws-re "\\_>") . 1) 448 (,(concat "(\\(catch\\|throw\\|provide\\|require\\)\\_>"
449 ;; Exit/Feature symbols as constants. 449 "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?")
450 (,(concat "(\\(catch\\|throw\\|provide\\|require\\)\\_>" 450 (1 font-lock-keyword-face)
451 "[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?") 451 (2 font-lock-constant-face nil t))
452 (1 font-lock-keyword-face) 452 ;; Erroneous structures.
453 (2 font-lock-constant-face nil t)) 453 (,(concat "(" cl-errs-re "\\_>")
454 ;; Erroneous structures. 454 (1 font-lock-warning-face))
455 (,(concat "(" cl-errs-re "\\_>") 455 ;; Words inside `' tend to be symbol names.
456 (1 font-lock-warning-face)) 456 ("`\\(\\(?:\\sw\\|\\s_\\)\\(?:\\sw\\|\\s_\\)+\\)'"
457 ;; Words inside `' tend to be symbol names. 457 (1 font-lock-constant-face prepend))
458 ("`\\(\\(?:\\sw\\|\\s_\\)\\(?:\\sw\\|\\s_\\)+\\)'" 458 ;; Constant values.
459 (1 font-lock-constant-face prepend)) 459 ("\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" 0 font-lock-builtin-face)
460 ;; Constant values. 460 ;; ELisp and CLisp `&' keywords as types.
461 ("\\_<:\\(?:\\sw\\|\\s_\\)+\\_>" 0 font-lock-builtin-face) 461 ("\\_<\\&\\(?:\\sw\\|\\s_\\)+\\_>" . font-lock-type-face)
462 ;; ELisp and CLisp `&' keywords as types. 462 ;; This is too general -- rms.
463 ("\\_<\\&\\(?:\\sw\\|\\s_\\)+\\_>" . font-lock-type-face) 463 ;; A user complained that he has functions whose names start with `do'
464 ;; This is too general -- rms. 464 ;; and that they get the wrong color.
465 ;; A user complained that he has functions whose names start with `do' 465 ;; ;; CL `with-' and `do-' constructs
466 ;; and that they get the wrong color. 466 ;;("(\\(\\(do-\\|with-\\)\\(\\s_\\|\\w\\)*\\)" 1 font-lock-keyword-face)
467 ;; ;; CL `with-' and `do-' constructs 467 (lisp--match-hidden-arg
468 ;;("(\\(\\(do-\\|with-\\)\\(\\s_\\|\\w\\)*\\)" 1 font-lock-keyword-face) 468 (0 '(face font-lock-warning-face
469 (lisp--match-hidden-arg 469 help-echo "Hidden behind deeper element; move to another line?")))
470 (0 '(face font-lock-warning-face 470 ))
471 help-echo "Hidden behind deeper element; move to another line?"))) 471 "Gaudy level highlighting for Lisp modes.")))
472 ))
473 "Gaudy level highlighting for Lisp modes."))
474 472
475(define-obsolete-variable-alias 'lisp-font-lock-keywords 473(define-obsolete-variable-alias 'lisp-font-lock-keywords
476 'lisp-el-font-lock-keywords "24.4") 474 'lisp-el-font-lock-keywords "24.4")
diff --git a/lisp/subr.el b/lisp/subr.el
index 9c56e51bc96..b9a847d76e8 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1502,6 +1502,19 @@ All symbols are bound before the VALUEFORMs are evalled."
1502 ,@(mapcar (lambda (binder) `(setq ,@binder)) binders) 1502 ,@(mapcar (lambda (binder) `(setq ,@binder)) binders)
1503 ,@body)) 1503 ,@body))
1504 1504
1505(defmacro let-when-compile (bindings &rest body)
1506 "Like `let', but allow for compile time optimization.
1507Use BINDINGS as in regular `let', but in BODY each usage should
1508be wrapped in `eval-when-compile'.
1509This will generate compile-time constants from BINDINGS."
1510 (declare (indent 1) (debug let))
1511 (cl-progv (mapcar #'car bindings)
1512 (mapcar (lambda (x) (eval (cadr x))) bindings)
1513 (macroexpand-all
1514 (macroexp-progn
1515 body)
1516 macroexpand-all-environment)))
1517
1505(defmacro with-wrapper-hook (hook args &rest body) 1518(defmacro with-wrapper-hook (hook args &rest body)
1506 "Run BODY, using wrapper functions from HOOK with additional ARGS. 1519 "Run BODY, using wrapper functions from HOOK with additional ARGS.
1507HOOK is an abnormal hook. Each hook function in HOOK \"wraps\" 1520HOOK is an abnormal hook. Each hook function in HOOK \"wraps\"