comparison lisp/emacs-lisp/lisp-mode.el @ 51261:a3a1d78e827e

(lisp-font-lock-syntactic-face-function): Don't infinite lop at bob. (emacs-lisp-mode): Mark its main custom group to be `lisp'. (prin1-char): New fun. (eval-last-sexp-1): Use it. Use with-syntax-table as well. (eval-defun-1): Don't replace `defvar' with `defconst'.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Tue, 27 May 2003 14:17:17 +0000
parents 152c21ba1618
children 0e0d3c3dca7f
comparison
equal deleted inserted replaced
51260:a51376ab4a2e 51261:a3a1d78e827e
1 ;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands 1 ;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands
2 2
3 ;; Copyright (C) 1985, 1986, 1999, 2000, 2001 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985, 1986, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
4 4
5 ;; Maintainer: FSF 5 ;; Maintainer: FSF
6 ;; Keywords: lisp, languages 6 ;; Keywords: lisp, languages
7 7
8 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
144 ;; This might be a docstring. 144 ;; This might be a docstring.
145 (save-excursion 145 (save-excursion
146 (let ((n 0)) 146 (let ((n 0))
147 (goto-char (nth 8 state)) 147 (goto-char (nth 8 state))
148 (condition-case nil 148 (condition-case nil
149 (while (progn (backward-sexp 1) (setq n (1+ n)))) 149 (while (and (not (bobp))
150 (progn (backward-sexp 1) (setq n (1+ n)))))
150 (scan-error nil)) 151 (scan-error nil))
151 (when (> n 0) 152 (when (> n 0)
152 (let ((sym (intern-soft 153 (let ((sym (intern-soft
153 (buffer-substring 154 (buffer-substring
154 (point) (progn (forward-sexp 1) (point)))))) 155 (point) (progn (forward-sexp 1) (point))))))
318 (setq major-mode 'emacs-lisp-mode) 319 (setq major-mode 'emacs-lisp-mode)
319 (setq mode-name "Emacs-Lisp") 320 (setq mode-name "Emacs-Lisp")
320 (lisp-mode-variables) 321 (lisp-mode-variables)
321 (setq imenu-case-fold-search nil) 322 (setq imenu-case-fold-search nil)
322 (run-hooks 'emacs-lisp-mode-hook)) 323 (run-hooks 'emacs-lisp-mode-hook))
324 (put 'emacs-lisp-mode 'custom-mode-group 'lisp)
323 325
324 (defvar lisp-mode-map 326 (defvar lisp-mode-map
325 (let ((map (make-sparse-keymap))) 327 (let ((map (make-sparse-keymap)))
326 (set-keymap-parent map lisp-mode-shared-map) 328 (set-keymap-parent map lisp-mode-shared-map)
327 (define-key map "\e\C-x" 'lisp-eval-defun) 329 (define-key map "\e\C-x" 'lisp-eval-defun)
443 (nth 0 value) 445 (nth 0 value)
444 (nth 2 value) 446 (nth 2 value)
445 (nth 1 value)) 447 (nth 1 value))
446 (goto-char (min (point-max) point))))))) 448 (goto-char (min (point-max) point)))))))
447 449
450 (defun prin1-char (char)
451 "Return a string representing CHAR as a character rather than as an integer.
452 If CHAR is not a character, return nil."
453 (and (integerp char)
454 (char-valid-p (event-basic-type char))
455 (concat
456 "?"
457 (mapconcat
458 (lambda (modif)
459 (cond ((eq modif 'super) "\\s-")
460 (t (string ?\\ (upcase (aref (symbol-name modif) 0)) ?-))))
461 (event-modifiers char) "")
462 (string (event-basic-type char)))))
463
448 (defun eval-last-sexp-1 (eval-last-sexp-arg-internal) 464 (defun eval-last-sexp-1 (eval-last-sexp-arg-internal)
449 "Evaluate sexp before point; print value in minibuffer. 465 "Evaluate sexp before point; print value in minibuffer.
450 With argument, print output into current buffer." 466 With argument, print output into current buffer."
451 (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t))) 467 (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t)))
452 (let ((value 468 (let ((value
453 (eval (let ((stab (syntax-table)) 469 (eval (let ((stab (syntax-table))
454 (opoint (point)) 470 (opoint (point))
455 ignore-quotes 471 ignore-quotes
456 expr) 472 expr)
457 (unwind-protect 473 (with-syntax-table emacs-lisp-mode-syntax-table
458 (save-excursion 474 ;; If this sexp appears to be enclosed in `...'
459 (set-syntax-table emacs-lisp-mode-syntax-table) 475 ;; then ignore the surrounding quotes.
460 ;; If this sexp appears to be enclosed in `...' 476 (setq ignore-quotes
461 ;; then ignore the surrounding quotes. 477 (or (eq (following-char) ?\')
462 (setq ignore-quotes 478 (eq (preceding-char) ?\')))
463 (or (eq (following-char) ?\') 479 (forward-sexp -1)
464 (eq (preceding-char) ?\'))) 480 ;; If we were after `?\e' (or similar case),
465 (forward-sexp -1) 481 ;; use the whole thing, not just the `e'.
466 ;; If we were after `?\e' (or similar case), 482 (when (eq (preceding-char) ?\\)
467 ;; use the whole thing, not just the `e'. 483 (forward-char -1)
468 (when (eq (preceding-char) ?\\) 484 (when (eq (preceding-char) ??)
469 (forward-char -1) 485 (forward-char -1)))
470 (when (eq (preceding-char) ??) 486
471 (forward-char -1))) 487 ;; Skip over `#N='s.
472 488 (when (eq (preceding-char) ?=)
473 ;; Skip over `#N='s. 489 (let (labeled-p)
474 (when (eq (preceding-char) ?=) 490 (save-excursion
475 (let (labeled-p) 491 (skip-chars-backward "0-9#=")
476 (save-excursion 492 (setq labeled-p (looking-at "\\(#[0-9]+=\\)+")))
477 (skip-chars-backward "0-9#=") 493 (when labeled-p
478 (setq labeled-p (looking-at "\\(#[0-9]+=\\)+"))) 494 (forward-sexp -1))))
479 (when labeled-p 495
480 (forward-sexp -1)))) 496 (save-restriction
481 497 ;; vladimir@cs.ualberta.ca 30-Jul-1997: skip ` in
482 (save-restriction 498 ;; `variable' so that the value is returned, not the
483 ;; vladimir@cs.ualberta.ca 30-Jul-1997: skip ` in 499 ;; name
484 ;; `variable' so that the value is returned, not the 500 (if (and ignore-quotes
485 ;; name 501 (eq (following-char) ?`))
486 (if (and ignore-quotes 502 (forward-char))
487 (eq (following-char) ?`)) 503 (narrow-to-region (point-min) opoint)
488 (forward-char)) 504 (setq expr (read (current-buffer)))
489 (narrow-to-region (point-min) opoint) 505 ;; If it's an (interactive ...) form, it's more
490 (setq expr (read (current-buffer))) 506 ;; useful to show how an interactive call would
491 ;; If it's an (interactive ...) form, it's more 507 ;; use it.
492 ;; useful to show how an interactive call would 508 (and (consp expr)
493 ;; use it. 509 (eq (car expr) 'interactive)
494 (and (consp expr) 510 (setq expr
495 (eq (car expr) 'interactive) 511 (list 'call-interactively
496 (setq expr 512 (list 'quote
497 (list 'call-interactively 513 (list 'lambda
498 (list 'quote 514 '(&rest args)
499 (list 'lambda 515 expr
500 '(&rest args) 516 'args)))))
501 expr 517 expr))))))
502 'args)))))
503 expr))
504 (set-syntax-table stab))))))
505 (let ((unabbreviated (let ((print-length nil) (print-level nil)) 518 (let ((unabbreviated (let ((print-length nil) (print-level nil))
506 (prin1-to-string value))) 519 (prin1-to-string value)))
507 (print-length eval-expression-print-length) 520 (print-length eval-expression-print-length)
508 (print-level eval-expression-print-level) 521 (print-level eval-expression-print-level)
522 (char-string (prin1-char value))
509 (beg (point)) 523 (beg (point))
510 end) 524 end)
511 (prog1 525 (prog1
512 (prin1 value) 526 (prin1 value)
527 (if (and (eq standard-output t) char-string)
528 (princ (concat " = " char-string)))
513 (setq end (point)) 529 (setq end (point))
514 (when (and (bufferp standard-output) 530 (when (and (bufferp standard-output)
515 (or (not (null print-length)) 531 (or (not (null print-length))
516 (not (null print-level))) 532 (not (null print-level)))
517 (not (string= unabbreviated 533 (not (string= unabbreviated
542 ;; The code in edebug-defun should be consistent with this, but not 558 ;; The code in edebug-defun should be consistent with this, but not
543 ;; the same, since this gets a macroexpended form. 559 ;; the same, since this gets a macroexpended form.
544 (cond ((not (listp form)) 560 (cond ((not (listp form))
545 form) 561 form)
546 ((and (eq (car form) 'defvar) 562 ((and (eq (car form) 'defvar)
547 (cdr-safe (cdr-safe form))) 563 (cdr-safe (cdr-safe form))
548 ;; Force variable to be bound. 564 (boundp (cadr form)))
549 (cons 'defconst (cdr form))) 565 ;; Force variable to be re-set.
566 `(progn (defvar ,(nth 1 form) nil ,@(nthcdr 3 form))
567 (setq ,(nth 1 form) ,(nth 2 form))))
550 ;; `defcustom' is now macroexpanded to 568 ;; `defcustom' is now macroexpanded to
551 ;; `custom-declare-variable' with a quoted value arg. 569 ;; `custom-declare-variable' with a quoted value arg.
552 ((and (eq (car form) 'custom-declare-variable) 570 ((and (eq (car form) 'custom-declare-variable)
553 (default-boundp (eval (nth 1 form)))) 571 (default-boundp (eval (nth 1 form))))
554 ;; Force variable to be bound. 572 ;; Force variable to be bound.
832 (not (looking-at "\\sw\\|\\s_"))) 850 (not (looking-at "\\sw\\|\\s_")))
833 ;; car of form doesn't seem to be a symbol 851 ;; car of form doesn't seem to be a symbol
834 (progn 852 (progn
835 (if (not (> (save-excursion (forward-line 1) (point)) 853 (if (not (> (save-excursion (forward-line 1) (point))
836 calculate-lisp-indent-last-sexp)) 854 calculate-lisp-indent-last-sexp))
837 (progn (goto-char calculate-lisp-indent-last-sexp) 855 (progn (goto-char calculate-lisp-indent-last-sexp)
838 (beginning-of-line) 856 (beginning-of-line)
839 (parse-partial-sexp (point) 857 (parse-partial-sexp (point)
840 calculate-lisp-indent-last-sexp 0 t))) 858 calculate-lisp-indent-last-sexp 0 t)))
841 ;; Indent under the list or under the first sexp on the same 859 ;; Indent under the list or under the first sexp on the same
842 ;; line as calculate-lisp-indent-last-sexp. Note that first 860 ;; line as calculate-lisp-indent-last-sexp. Note that first
843 ;; thing on that line has to be complete sexp since we are 861 ;; thing on that line has to be complete sexp since we are
844 ;; inside the innermost containing sexp. 862 ;; inside the innermost containing sexp.
845 (backward-prefix-chars) 863 (backward-prefix-chars)
846 (current-column)) 864 (current-column))
847 (let ((function (buffer-substring (point) 865 (let ((function (buffer-substring (point)
848 (progn (forward-sexp 1) (point)))) 866 (progn (forward-sexp 1) (point))))