Spelling fixes.
[bpt/emacs.git] / lisp / emacs-lisp / lisp-mode.el
index 48f0b9b..f9e7fe4 100644 (file)
@@ -1,17 +1,17 @@
 ;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands
 
-;; Copyright (C) 1985, 1986, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1999-2011 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: lisp, languages
+;; Package: emacs
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,9 +19,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 (define-abbrev-table 'lisp-mode-abbrev-table ())
 
 (defvar emacs-lisp-mode-syntax-table
-  (let ((table (make-syntax-table)))
-    (let ((i 0))
-      (while (< i ?0)
-       (modify-syntax-entry i "_   " table)
-       (setq i (1+ i)))
-      (setq i (1+ ?9))
-      (while (< i ?A)
-       (modify-syntax-entry i "_   " table)
-       (setq i (1+ i)))
-      (setq i (1+ ?Z))
-      (while (< i ?a)
-       (modify-syntax-entry i "_   " table)
-       (setq i (1+ i)))
-      (setq i (1+ ?z))
-      (while (< i 128)
-       (modify-syntax-entry i "_   " table)
-       (setq i (1+ i)))
-      (modify-syntax-entry ?\s "    " table)
-      ;; Non-break space acts as whitespace.
-      (modify-syntax-entry ?\x8a0 "    " table)
-      (modify-syntax-entry ?\t "    " table)
-      (modify-syntax-entry ?\f "    " table)
-      (modify-syntax-entry ?\n ">   " table)
-      ;; This is probably obsolete since nowadays such features use overlays.
-      ;; ;; Give CR the same syntax as newline, for selective-display.
-      ;; (modify-syntax-entry ?\^m ">   " table)
-      (modify-syntax-entry ?\; "<   " table)
-      (modify-syntax-entry ?` "'   " table)
-      (modify-syntax-entry ?' "'   " table)
-      (modify-syntax-entry ?, "'   " table)
-      (modify-syntax-entry ?@ "'   " table)
-      ;; Used to be singlequote; changed for flonums.
-      (modify-syntax-entry ?. "_   " table)
-      (modify-syntax-entry ?# "'   " table)
-      (modify-syntax-entry ?\" "\"    " table)
-      (modify-syntax-entry ?\\ "\\   " table)
-      (modify-syntax-entry ?\( "()  " table)
-      (modify-syntax-entry ?\) ")(  " table)
-      (modify-syntax-entry ?\[ "(]  " table)
-      (modify-syntax-entry ?\] ")[  " table))
-    table))
+  (let ((table (make-syntax-table))
+        (i 0))
+    (while (< i ?0)
+      (modify-syntax-entry i "_   " table)
+      (setq i (1+ i)))
+    (setq i (1+ ?9))
+    (while (< i ?A)
+      (modify-syntax-entry i "_   " table)
+      (setq i (1+ i)))
+    (setq i (1+ ?Z))
+    (while (< i ?a)
+      (modify-syntax-entry i "_   " table)
+      (setq i (1+ i)))
+    (setq i (1+ ?z))
+    (while (< i 128)
+      (modify-syntax-entry i "_   " table)
+      (setq i (1+ i)))
+    (modify-syntax-entry ?\s "    " table)
+    ;; Non-break space acts as whitespace.
+    (modify-syntax-entry ?\x8a0 "    " table)
+    (modify-syntax-entry ?\t "    " table)
+    (modify-syntax-entry ?\f "    " table)
+    (modify-syntax-entry ?\n ">   " table)
+    ;; This is probably obsolete since nowadays such features use overlays.
+    ;; ;; Give CR the same syntax as newline, for selective-display.
+    ;; (modify-syntax-entry ?\^m ">   " table)
+    (modify-syntax-entry ?\; "<   " table)
+    (modify-syntax-entry ?` "'   " table)
+    (modify-syntax-entry ?' "'   " table)
+    (modify-syntax-entry ?, "'   " table)
+    (modify-syntax-entry ?@ "'   " table)
+    ;; Used to be singlequote; changed for flonums.
+    (modify-syntax-entry ?. "_   " table)
+    (modify-syntax-entry ?# "'   " table)
+    (modify-syntax-entry ?\" "\"    " table)
+    (modify-syntax-entry ?\\ "\\   " table)
+    (modify-syntax-entry ?\( "()  " table)
+    (modify-syntax-entry ?\) ")(  " table)
+    (modify-syntax-entry ?\[ "(]  " table)
+    (modify-syntax-entry ?\] ")[  " table)
+    table)
+  "Syntax table used in `emacs-lisp-mode'.")
 
 (defvar lisp-mode-syntax-table
   (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
     (modify-syntax-entry ?\[ "_   " table)
     (modify-syntax-entry ?\] "_   " table)
-    (modify-syntax-entry ?# "' 14b" table)
+    (modify-syntax-entry ?# "' 14" table)
     (modify-syntax-entry ?| "\" 23bn" table)
-    table))
+    table)
+  "Syntax table used in `lisp-mode'.")
 
 (defvar lisp-imenu-generic-expression
   (list
 (put 'defvar   'doc-string-elt 3)
 (put 'defcustom 'doc-string-elt 3)
 (put 'deftheme 'doc-string-elt 2)
+(put 'deftype 'doc-string-elt 3)
 (put 'defconst 'doc-string-elt 3)
 (put 'defmacro 'doc-string-elt 3)
 (put 'defmacro* 'doc-string-elt 3)
 (put 'defalias 'doc-string-elt 3)
 (put 'defvaralias 'doc-string-elt 3)
 (put 'define-category 'doc-string-elt 2)
+(put 'define-overloadable-function 'doc-string-elt 3)
 
 (defvar lisp-doc-string-elt-property 'doc-string-elt
   "The symbol property that holds the docstring position info.")
               font-lock-string-face))))
     font-lock-comment-face))
 
-;; The LISP-SYNTAX argument is used by code in inf-lisp.el and is
-;; (uselessly) passed from pp.el, chistory.el, gnus-kill.el and score-mode.el
-(defun lisp-mode-variables (&optional lisp-syntax)
+(defun lisp-mode-variables (&optional lisp-syntax keywords-case-insensitive)
+  "Common initialization routine for lisp modes.
+The LISP-SYNTAX argument is used by code in inf-lisp.el and is
+\(uselessly) passed from pp.el, chistory.el, gnus-kill.el and
+score-mode.el.  KEYWORDS-CASE-INSENSITIVE non-nil means that for
+font-lock keywords will not be case sensitive."
   (when lisp-syntax
     (set-syntax-table lisp-mode-syntax-table))
   (setq local-abbrev-table lisp-mode-abbrev-table)
   ;;(set (make-local-variable 'adaptive-fill-mode) nil)
   (make-local-variable 'indent-line-function)
   (setq indent-line-function 'lisp-indent-line)
-  (make-local-variable 'parse-sexp-ignore-comments)
-  (setq parse-sexp-ignore-comments t)
   (make-local-variable 'outline-regexp)
   (setq outline-regexp ";;;\\(;* [^ \t\n]\\|###autoload\\)\\|(")
   (make-local-variable 'outline-level)
   (setq multibyte-syntax-as-symbol t)
   (set (make-local-variable 'syntax-begin-function) 'beginning-of-defun)
   (setq font-lock-defaults
-       '((lisp-font-lock-keywords
+       `((lisp-font-lock-keywords
           lisp-font-lock-keywords-1 lisp-font-lock-keywords-2)
-         nil nil (("+-*/.<>=!?$%_&~^:@" . "w")) nil
+         nil ,keywords-case-insensitive (("+-*/.<>=!?$%_&~^:@" . "w")) nil
          (font-lock-mark-block-function . mark-defun)
          (font-lock-syntactic-face-function
           . lisp-font-lock-syntactic-face-function))))
 (defvar emacs-lisp-mode-map
   (let ((map (make-sparse-keymap "Emacs-Lisp"))
        (menu-map (make-sparse-keymap "Emacs-Lisp"))
+       (lint-map (make-sparse-keymap))
        (prof-map (make-sparse-keymap))
        (tracing-map (make-sparse-keymap)))
     (set-keymap-parent map lisp-mode-shared-map)
-    (define-key map "\e\t" 'lisp-complete-symbol)
+    (define-key map "\e\t" 'completion-at-point)
     (define-key map "\e\C-x" 'eval-defun)
     (define-key map "\e\C-q" 'indent-pp-sexp)
-    (define-key map [menu-bar emacs-lisp] (cons "Emacs-Lisp" menu-map))
+    (define-key map [menu-bar emacs-lisp] (cons (purecopy "Emacs-Lisp") menu-map))
     (define-key menu-map [eldoc]
-      '(menu-item "Auto-Display Documentation Strings" eldoc-mode
+      `(menu-item ,(purecopy "Auto-Display Documentation Strings") eldoc-mode
                  :button (:toggle . (bound-and-true-p eldoc-mode))
-                 :help "Display the documentation string for the item under cursor"))
+                 :help ,(purecopy "Display the documentation string for the item under cursor")))
     (define-key menu-map [checkdoc]
-      '(menu-item "Check Documentation Strings" checkdoc
-                 :help "Check documentation strings for style requirements"))
+      `(menu-item ,(purecopy "Check Documentation Strings") checkdoc
+                 :help ,(purecopy "Check documentation strings for style requirements")))
     (define-key menu-map [re-builder]
-      '(menu-item "Construct Regexp" re-builder
-                 :help "Construct a regexp interactively"))
-    (define-key menu-map [tracing] (cons "Tracing" tracing-map))
+      `(menu-item ,(purecopy "Construct Regexp") re-builder
+                 :help ,(purecopy "Construct a regexp interactively")))
+    (define-key menu-map [tracing] (cons (purecopy "Tracing") tracing-map))
     (define-key tracing-map [tr-a]
-      '(menu-item "Untrace all" untrace-all
-                 :help "Untraces all currently traced functions"))
+      `(menu-item ,(purecopy "Untrace All") untrace-all
+                 :help ,(purecopy "Untrace all currently traced functions")))
     (define-key tracing-map [tr-uf]
-      '(menu-item "Untrace function..." untrace-function
-                 :help "Untraces FUNCTION and possibly activates all remaining advice"))
-    (define-key tracing-map [tr-sep] '("--"))
+      `(menu-item ,(purecopy "Untrace Function...") untrace-function
+                 :help ,(purecopy "Untrace function, and possibly activate all remaining advice")))
+    (define-key tracing-map [tr-sep] menu-bar-separator)
     (define-key tracing-map [tr-q]
-      '(menu-item "Trace function quietly..." trace-function-background
-                 :help "Trace the function with trace output going quietly to a buffer"))
+      `(menu-item ,(purecopy "Trace Function Quietly...") trace-function-background
+                 :help ,(purecopy "Trace the function with trace output going quietly to a buffer")))
     (define-key tracing-map [tr-f]
-      '(menu-item "Trace function..." trace-function
-                 :help "Trace the function given as a argument"))
-    (define-key menu-map [profiling] (cons "Profiling" prof-map))
+      `(menu-item ,(purecopy "Trace Function...") trace-function
+                 :help ,(purecopy "Trace the function given as an argument")))
+    (define-key menu-map [profiling] (cons (purecopy "Profiling") prof-map))
     (define-key prof-map [prof-restall]
-      '(menu-item "Remove Instrumentation for All Functions" elp-restore-all
-                 :help "Restore the original definitions of all functions being profiled"))
+      `(menu-item ,(purecopy "Remove Instrumentation for All Functions") elp-restore-all
+                 :help ,(purecopy "Restore the original definitions of all functions being profiled")))
     (define-key prof-map [prof-restfunc]
-      '(menu-item "Remove Instrumentation for Function..." elp-restore-function
-                 :help "Restore an instrumented function to its original definition"))
+      `(menu-item ,(purecopy "Remove Instrumentation for Function...") elp-restore-function
+                 :help ,(purecopy "Restore an instrumented function to its original definition")))
 
-    (define-key prof-map [sep-rem] '("--"))
+    (define-key prof-map [sep-rem] menu-bar-separator)
     (define-key prof-map [prof-resall]
-      '(menu-item "Reset Counters for All Functions" elp-reset-all
-                 :help "Reset the profiling information for all functions being profiled"))
+      `(menu-item ,(purecopy "Reset Counters for All Functions") elp-reset-all
+                 :help ,(purecopy "Reset the profiling information for all functions being profiled")))
     (define-key prof-map [prof-resfunc]
-      '(menu-item "Reset Counters for Function..." elp-reset-function
-                 :help "Reset the profiling information for a function"))
+      `(menu-item ,(purecopy "Reset Counters for Function...") elp-reset-function
+                 :help ,(purecopy "Reset the profiling information for a function")))
     (define-key prof-map [prof-res]
-      '(menu-item "Show Profiling Results" elp-results
-                 :help "Display current profiling results"))
+      `(menu-item ,(purecopy "Show Profiling Results") elp-results
+                 :help ,(purecopy "Display current profiling results")))
     (define-key prof-map [prof-pack]
-      '(menu-item "Instrument Package..." elp-instrument-package
-                 :help "Instrument for profiling all function that start with a prefix"))
+      `(menu-item ,(purecopy "Instrument Package...") elp-instrument-package
+                 :help ,(purecopy "Instrument for profiling all function that start with a prefix")))
     (define-key prof-map [prof-func]
-      '(menu-item "Instrument Function..." elp-instrument-function
-                 :help "Instrument a function for profiling"))
+      `(menu-item ,(purecopy "Instrument Function...") elp-instrument-function
+                 :help ,(purecopy "Instrument a function for profiling")))
+    (define-key menu-map [lint] (cons (purecopy "Linting") lint-map))
+    (define-key lint-map [lint-di]
+      `(menu-item ,(purecopy "Lint Directory...") elint-directory
+                 :help ,(purecopy "Lint a directory")))
+    (define-key lint-map [lint-f]
+      `(menu-item ,(purecopy "Lint File...") elint-file
+                 :help ,(purecopy "Lint a file")))
+    (define-key lint-map [lint-b]
+      `(menu-item ,(purecopy "Lint Buffer") elint-current-buffer
+                 :help ,(purecopy "Lint the current buffer")))
+    (define-key lint-map [lint-d]
+      `(menu-item ,(purecopy "Lint Defun") elint-defun
+                 :help ,(purecopy "Lint the function at point")))
     (define-key menu-map [edebug-defun]
-      '(menu-item "Instrument Function for Debugging" edebug-defun
-                 :help "Evaluate the top level form point is in, stepping through with Edebug"
-                 :keys "C-u C-M-x"))
-    (define-key menu-map [separator-byte] '("--"))
+      `(menu-item ,(purecopy "Instrument Function for Debugging") edebug-defun
+                 :help ,(purecopy "Evaluate the top level form point is in, stepping through with Edebug")
+                 :keys ,(purecopy "C-u C-M-x")))
+    (define-key menu-map [separator-byte] menu-bar-separator)
     (define-key menu-map [disas]
-      '(menu-item "Disassemble byte compiled object..." disassemble
-                 :help "Print disassembled code for OBJECT in a buffer"))
+      `(menu-item ,(purecopy "Disassemble Byte Compiled Object...") disassemble
+                 :help ,(purecopy "Print disassembled code for OBJECT in a buffer")))
     (define-key menu-map [byte-recompile]
-      '(menu-item "Byte-recompile Directory..." byte-recompile-directory
-                 :help "Recompile every `.el' file in DIRECTORY that needs recompilation"))
+      `(menu-item ,(purecopy "Byte-recompile Directory...") byte-recompile-directory
+                 :help ,(purecopy "Recompile every `.el' file in DIRECTORY that needs recompilation")))
     (define-key menu-map [emacs-byte-compile-and-load]
-      '(menu-item "Byte-compile And Load" emacs-lisp-byte-compile-and-load
-                 :help "Byte-compile the current file (if it has changed), then load compiled code"))
+      `(menu-item ,(purecopy "Byte-compile and Load") emacs-lisp-byte-compile-and-load
+                 :help ,(purecopy "Byte-compile the current file (if it has changed), then load compiled code")))
     (define-key menu-map [byte-compile]
-      '(menu-item "Byte-compile This File" emacs-lisp-byte-compile
-                 :help "Byte compile the file containing the current buffer"))
-    (define-key menu-map [separator-eval] '("--"))
+      `(menu-item ,(purecopy "Byte-compile This File") emacs-lisp-byte-compile
+                 :help ,(purecopy "Byte compile the file containing the current buffer")))
+    (define-key menu-map [separator-eval] menu-bar-separator)
     (define-key menu-map [ielm]
-      '(menu-item "Interactive Expression Evaluation" ielm
-                 :help "Interactively evaluate Emacs Lisp expressions"))
+      `(menu-item ,(purecopy "Interactive Expression Evaluation") ielm
+                 :help ,(purecopy "Interactively evaluate Emacs Lisp expressions")))
     (define-key menu-map [eval-buffer]
-      '(menu-item "Evaluate Buffer" eval-buffer
-                 :help "Execute the current buffer as Lisp code"))
+      `(menu-item ,(purecopy "Evaluate Buffer") eval-buffer
+                 :help ,(purecopy "Execute the current buffer as Lisp code")))
     (define-key menu-map [eval-region]
-      '(menu-item "Evaluate Region" eval-region
-                 :help "Execute the region as Lisp code"
+      `(menu-item ,(purecopy "Evaluate Region") eval-region
+                 :help ,(purecopy "Execute the region as Lisp code")
                  :enable mark-active))
     (define-key menu-map [eval-sexp]
-      '(menu-item "Evaluate Last S-expression" eval-last-sexp
-                 :help "Evaluate sexp before point; print value in minibuffer"))
-    (define-key menu-map [separator-format] '("--"))
+      `(menu-item ,(purecopy "Evaluate Last S-expression") eval-last-sexp
+                 :help ,(purecopy "Evaluate sexp before point; print value in minibuffer")))
+    (define-key menu-map [separator-format] menu-bar-separator)
     (define-key menu-map [comment-region]
-      '(menu-item "Comment Out Region" comment-region
-                 :help "Comment or uncomment each line in the region"
+      `(menu-item ,(purecopy "Comment Out Region") comment-region
+                 :help ,(purecopy "Comment or uncomment each line in the region")
                  :enable mark-active))
     (define-key menu-map [indent-region]
-      '(menu-item "Indent Region" indent-region
-                 :help "Indent each nonblank line in the region"
+      `(menu-item ,(purecopy "Indent Region") indent-region
+                 :help ,(purecopy "Indent each nonblank line in the region")
                  :enable mark-active))
-    (define-key menu-map [indent-line] '("Indent Line" . lisp-indent-line))
+    (define-key menu-map [indent-line]
+      `(menu-item ,(purecopy "Indent Line") lisp-indent-line))
     map)
   "Keymap for Emacs Lisp mode.
 All commands in `lisp-mode-shared-map' are inherited by this map.")
@@ -388,10 +406,7 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
   (if (and (buffer-modified-p)
           (y-or-n-p (format "Save buffer %s first? " (buffer-name))))
       (save-buffer))
-  (let ((compiled-file-name (byte-compile-dest-file buffer-file-name)))
-    (if (file-newer-than-file-p compiled-file-name buffer-file-name)
-       (load-file compiled-file-name)
-      (byte-compile-file buffer-file-name t))))
+  (byte-recompile-file buffer-file-name nil 0 t))
 
 (defcustom emacs-lisp-mode-hook nil
   "Hook run when entering Emacs Lisp mode."
@@ -411,60 +426,59 @@ All commands in `lisp-mode-shared-map' are inherited by this map.")
   :type 'hook
   :group 'lisp)
 
-(defun emacs-lisp-mode ()
+(define-derived-mode emacs-lisp-mode prog-mode "Emacs-Lisp"
   "Major mode for editing Lisp code to run in Emacs.
 Commands:
 Delete converts tabs to spaces as it moves back.
 Blank lines separate paragraphs.  Semicolons start comments.
+
 \\{emacs-lisp-mode-map}
 Entry to this mode calls the value of `emacs-lisp-mode-hook'
 if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map emacs-lisp-mode-map)
-  (set-syntax-table emacs-lisp-mode-syntax-table)
-  (setq major-mode 'emacs-lisp-mode)
-  (setq mode-name "Emacs-Lisp")
+  :group 'lisp
   (lisp-mode-variables)
   (setq imenu-case-fold-search nil)
-  (run-mode-hooks 'emacs-lisp-mode-hook))
-(put 'emacs-lisp-mode 'custom-mode-group 'lisp)
+  (add-hook 'completion-at-point-functions
+            'lisp-completion-at-point nil 'local))
 
 (defvar lisp-mode-map
-  (let ((map (make-sparse-keymap)))
+  (let ((map (make-sparse-keymap))
+       (menu-map (make-sparse-keymap "Lisp")))
     (set-keymap-parent map lisp-mode-shared-map)
     (define-key map "\e\C-x" 'lisp-eval-defun)
     (define-key map "\C-c\C-z" 'run-lisp)
+    (define-key map [menu-bar lisp] (cons (purecopy "Lisp") menu-map))
+    (define-key menu-map [run-lisp]
+      `(menu-item ,(purecopy "Run inferior Lisp") run-lisp
+                 :help ,(purecopy "Run an inferior Lisp process, input and output via buffer `*inferior-lisp*'")))
+    (define-key menu-map [ev-def]
+      `(menu-item ,(purecopy "Eval defun") lisp-eval-defun
+                 :help ,(purecopy "Send the current defun to the Lisp process made by M-x run-lisp")))
+    (define-key menu-map [ind-sexp]
+      `(menu-item ,(purecopy "Indent sexp") indent-sexp
+                 :help ,(purecopy "Indent each line of the list starting just after point")))
     map)
   "Keymap for ordinary Lisp mode.
 All commands in `lisp-mode-shared-map' are inherited by this map.")
 
-(defun lisp-mode ()
+(define-derived-mode lisp-mode prog-mode "Lisp"
   "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
 Commands:
 Delete converts tabs to spaces as it moves back.
 Blank lines separate paragraphs.  Semicolons start comments.
+
 \\{lisp-mode-map}
 Note that `run-lisp' may be used either to start an inferior Lisp job
 or to switch back to an existing one.
 
 Entry to this mode calls the value of `lisp-mode-hook'
 if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map lisp-mode-map)
-  (setq major-mode 'lisp-mode)
-  (setq mode-name "Lisp")
-  (lisp-mode-variables)
+  (lisp-mode-variables nil t)
+  (set (make-local-variable 'find-tag-default-function) 'lisp-find-tag-default)
   (make-local-variable 'comment-start-skip)
   (setq comment-start-skip
        "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *")
-  (make-local-variable 'font-lock-keywords-case-fold-search)
-  (setq font-lock-keywords-case-fold-search t)
-  (setq imenu-case-fold-search t)
-  (set-syntax-table lisp-mode-syntax-table)
-  (run-mode-hooks 'lisp-mode-hook))
-(put 'lisp-mode 'find-tag-default-function 'lisp-find-tag-default)
+  (setq imenu-case-fold-search t))
 
 (defun lisp-find-tag-default ()
   (let ((default (find-tag-default)))
@@ -488,30 +502,29 @@ if that value is non-nil."
     (set-keymap-parent map lisp-mode-shared-map)
     (define-key map "\e\C-x" 'eval-defun)
     (define-key map "\e\C-q" 'indent-pp-sexp)
-    (define-key map "\e\t" 'lisp-complete-symbol)
+    (define-key map "\e\t" 'completion-at-point)
     (define-key map "\n" 'eval-print-last-sexp)
-    (define-key map [menu-bar lisp-interaction] (cons "Lisp-Interaction" menu-map))
+    (define-key map [menu-bar lisp-interaction] (cons (purecopy "Lisp-Interaction") menu-map))
     (define-key menu-map [eval-defun]
-      '(menu-item "Evaluate Defun" eval-defun
-                 :help "Evaluate the top-level form containing point, or after point"))
+      `(menu-item ,(purecopy "Evaluate Defun") eval-defun
+                 :help ,(purecopy "Evaluate the top-level form containing point, or after point")))
     (define-key menu-map [eval-print-last-sexp]
-      '(menu-item "Evaluate and print" eval-print-last-sexp
-                 :help "Evaluate sexp before point; print value into current buffer"))
+      `(menu-item ,(purecopy "Evaluate and Print") eval-print-last-sexp
+                 :help ,(purecopy "Evaluate sexp before point; print value into current buffer")))
     (define-key menu-map [edebug-defun-lisp-interaction]
-      '(menu-item "Instrument Function for Debugging" edebug-defun
-                 :help "Evaluate the top level form point is in, stepping through with Edebug"
-                 :keys "C-u C-M-x"))
+      `(menu-item ,(purecopy "Instrument Function for Debugging") edebug-defun
+                 :help ,(purecopy "Evaluate the top level form point is in, stepping through with Edebug")
+                 :keys ,(purecopy "C-u C-M-x")))
     (define-key menu-map [indent-pp-sexp]
-      '(menu-item "Indent or Pretty-Print" indent-pp-sexp
-                 :help "Indent each line of the list starting just after point, or prettyprint it"))
-    (define-key menu-map [lisp-complete-symbol]
-      '(menu-item "Complete Lisp Symbol" lisp-complete-symbol
-                 :help "Perform completion on Lisp symbol preceding point"))
+      `(menu-item ,(purecopy "Indent or Pretty-Print") indent-pp-sexp
+                 :help ,(purecopy "Indent each line of the list starting just after point, or prettyprint it")))
+    (define-key menu-map [complete-symbol]
+      `(menu-item ,(purecopy "Complete Lisp Symbol") completion-at-point
+                 :help ,(purecopy "Perform completion on Lisp symbol preceding point")))
     map)
   "Keymap for Lisp Interaction mode.
 All commands in `lisp-mode-shared-map' are inherited by this map.")
 
-(defvar lisp-interaction-mode-abbrev-table lisp-mode-abbrev-table)
 (define-derived-mode lisp-interaction-mode emacs-lisp-mode "Lisp Interaction"
   "Major mode for typing and evaluating Lisp forms.
 Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression
@@ -523,6 +536,7 @@ Commands:
 Delete converts tabs to spaces as it moves back.
 Paragraphs are separated only by blank lines.
 Semicolons start comments.
+
 \\{lisp-interaction-mode-map}
 Entry to this mode calls the value of `lisp-interaction-mode-hook'
 if that value is non-nil.")
@@ -642,6 +656,11 @@ If CHAR is not a character, return nil."
          (when (eq (preceding-char) ??)
            (forward-char -1)))
 
+       ;; Skip over hash table read syntax.
+       (and (> (point) (1+ (point-min)))
+            (looking-back "#s" (- (point) 2))
+            (forward-char -2))
+
        ;; Skip over `#N='s.
        (when (eq (preceding-char) ?=)
          (let (labeled-p)
@@ -679,7 +698,9 @@ If CHAR is not a character, return nil."
   "Evaluate sexp before point; print value in minibuffer.
 With argument, print output into current buffer."
   (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t)))
-    (eval-last-sexp-print-value (eval (preceding-sexp)))))
+    ;; Setup the lexical environment if lexical-binding is enabled.
+    (eval-last-sexp-print-value
+     (eval (eval-sexp-add-defvars (preceding-sexp)) lexical-binding))))
 
 
 (defun eval-last-sexp-print-value (value)
@@ -707,9 +728,28 @@ With argument, print output into current buffer."
 
 (defvar eval-last-sexp-fake-value (make-symbol "t"))
 
+(defun eval-sexp-add-defvars (exp &optional pos)
+  "Prepend EXP with all the `defvar's that precede it in the buffer.
+POS specifies the starting position where EXP was found and defaults to point."
+  (if (not lexical-binding)
+      exp
+    (save-excursion
+      (unless pos (setq pos (point)))
+      (let ((vars ()))
+        (goto-char (point-min))
+        (while (re-search-forward
+                "^(def\\(?:var\\|const\\|custom\\)[ \t\n]+\\([^; '()\n\t]+\\)"
+                pos t)
+          (let ((var (intern (match-string 1))))
+            (unless (special-variable-p var)
+              (push var vars))))
+        `(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp)))))
+
 (defun eval-last-sexp (eval-last-sexp-arg-internal)
   "Evaluate sexp before point; print value in minibuffer.
 Interactively, with prefix argument, print output into current buffer.
+Truncates long output according to the value of the variables
+`eval-expression-print-length' and `eval-expression-print-level'.
 
 If `eval-expression-debug-on-error' is non-nil, which is the default,
 this command arranges for all errors to enter the debugger."
@@ -729,7 +769,7 @@ this command arranges for all errors to enter the debugger."
 Reset the `defvar' and `defcustom' variables to the initial value.
 Reinitialize the face according to the `defface' specification."
   ;; The code in edebug-defun should be consistent with this, but not
-  ;; the same, since this gets a macroexpended form.
+  ;; the same, since this gets a macroexpanded form.
   (cond ((not (listp form))
         form)
        ((and (eq (car form) 'defvar)
@@ -741,30 +781,33 @@ Reinitialize the face according to the `defface' specification."
        ;; `defcustom' is now macroexpanded to
        ;; `custom-declare-variable' with a quoted value arg.
        ((and (eq (car form) 'custom-declare-variable)
-             (default-boundp (eval (nth 1 form))))
+             (default-boundp (eval (nth 1 form) lexical-binding)))
         ;; Force variable to be bound.
-        (set-default (eval (nth 1 form)) (eval (nth 1 (nth 2 form))))
+        (set-default (eval (nth 1 form) lexical-binding)
+                      (eval (nth 1 (nth 2 form)) lexical-binding))
         form)
        ;; `defface' is macroexpanded to `custom-declare-face'.
        ((eq (car form) 'custom-declare-face)
         ;; Reset the face.
-        (setq face-new-frame-defaults
-              (assq-delete-all (eval (nth 1 form)) face-new-frame-defaults))
-        (put (eval (nth 1 form)) 'face-defface-spec nil)
-        ;; Setting `customized-face' to the new spec after calling
-        ;; the form, but preserving the old saved spec in `saved-face',
-        ;; imitates the situation when the new face spec is set
-        ;; temporarily for the current session in the customize
-        ;; buffer, thus allowing `face-user-default-spec' to use the
-        ;; new customized spec instead of the saved spec.
-        ;; Resetting `saved-face' temporarily to nil is needed to let
-        ;; `defface' change the spec, regardless of a saved spec.
-        (prog1 `(prog1 ,form
-                  (put ,(nth 1 form) 'saved-face
-                       ',(get (eval (nth 1 form)) 'saved-face))
-                  (put ,(nth 1 form) 'customized-face
-                       ,(nth 2 form)))
-          (put (eval (nth 1 form)) 'saved-face nil)))
+        (let ((face-symbol (eval (nth 1 form) lexical-binding)))
+          (setq face-new-frame-defaults
+                (assq-delete-all face-symbol face-new-frame-defaults))
+          (put face-symbol 'face-defface-spec nil)
+          (put face-symbol 'face-documentation (nth 3 form))
+          ;; Setting `customized-face' to the new spec after calling
+          ;; the form, but preserving the old saved spec in `saved-face',
+          ;; imitates the situation when the new face spec is set
+          ;; temporarily for the current session in the customize
+          ;; buffer, thus allowing `face-user-default-spec' to use the
+          ;; new customized spec instead of the saved spec.
+          ;; Resetting `saved-face' temporarily to nil is needed to let
+          ;; `defface' change the spec, regardless of a saved spec.
+          (prog1 `(prog1 ,form
+                    (put ,(nth 1 form) 'saved-face
+                         ',(get face-symbol 'saved-face))
+                    (put ,(nth 1 form) 'customized-face
+                         ,(nth 2 form)))
+            (put face-symbol 'saved-face nil))))
        ((eq (car form) 'progn)
         (cons 'progn (mapcar 'eval-defun-1 (cdr form))))
        (t form)))
@@ -800,7 +843,7 @@ Return the result of evaluation."
           (end-of-defun)
           (beginning-of-defun)
           (setq beg (point))
-          (setq form (read (current-buffer)))
+          (setq form (eval-sexp-add-defvars (read (current-buffer))))
           (setq end (point)))
         ;; Alter the form if necessary.
         (setq form (eval-defun-1 (macroexpand form)))
@@ -860,11 +903,18 @@ which see."
 (defcustom lisp-indent-offset nil
   "If non-nil, indent second line of expressions that many more columns."
   :group 'lisp
-  :type '(choice nil integer))
-(put 'lisp-body-indent 'safe-local-variable
+  :type '(choice (const nil) integer))
+(put 'lisp-indent-offset 'safe-local-variable
      (lambda (x) (or (null x) (integerp x))))
 
-(defvar lisp-indent-function 'lisp-indent-function)
+(defcustom lisp-indent-function 'lisp-indent-function
+  "A function to be called by `calculate-lisp-indent'.
+It indents the arguments of a Lisp function call.  This function
+should accept two arguments: the indent-point, and the
+`parse-partial-sexp' state at that position.  One option for this
+function is `common-lisp-indent-function'."
+  :type 'function
+  :group 'lisp)
 
 (defun lisp-indent-line (&optional whole-exp)
   "Indent current line as Lisp code.
@@ -1018,7 +1068,10 @@ is the buffer position of the start of the containing expression."
                      ;; where it begins, so find that one, instead.
                      (save-excursion
                        (goto-char calculate-lisp-indent-last-sexp)
-                       (while (and (not (looking-back "^[ \t]*"))
+                      ;; Handle prefix characters and whitespace
+                      ;; following an open paren.  (Bug#1012)
+                       (backward-prefix-chars)
+                       (while (and (not (looking-back "^[ \t]*\\|([ \t]+"))
                                    (or (not containing-sexp)
                                        (< (1+ containing-sexp) (point))))
                          (forward-sexp -1)
@@ -1034,7 +1087,7 @@ is the buffer position of the start of the containing expression."
                        (goto-char calculate-lisp-indent-last-sexp)
                        (or (and (looking-at ":")
                                 (setq indent (current-column)))
-                           (and (< (save-excursion (beginning-of-line) (point))
+                           (and (< (line-beginning-position)
                                    (prog2 (backward-sexp) (point)))
                                 (looking-at ":")
                                 (setq indent (current-column))))
@@ -1049,25 +1102,31 @@ is the buffer position of the start of the containing expression."
 
 (defun lisp-indent-function (indent-point state)
   "This function is the normal value of the variable `lisp-indent-function'.
-It is used when indenting a line within a function call, to see if the
-called function says anything special about how to indent the line.
+The function `calculate-lisp-indent' calls this to determine
+if the arguments of a Lisp function call should be indented specially.
 
 INDENT-POINT is the position where the user typed TAB, or equivalent.
 Point is located at the point to indent under (for default indentation);
 STATE is the `parse-partial-sexp' state for that position.
 
-If the current line is in a call to a Lisp function
-which has a non-nil property `lisp-indent-function',
-that specifies how to do the indentation.  The property value can be
-* `defun', meaning indent `defun'-style;
+If the current line is in a call to a Lisp function that has a non-nil
+property `lisp-indent-function' (or the deprecated `lisp-indent-hook'),
+it specifies how to indent.  The property value can be:
+
+* `defun', meaning indent `defun'-style
+  \(this is also the case if there is no property and the function
+  has a name that begins with \"def\", and three or more arguments);
+
 * an integer N, meaning indent the first N arguments specially
-  like ordinary function arguments and then indent any further
+  (like ordinary function arguments), and then indent any further
   arguments like a body;
-* a function to call just as this function was called.
-  If that function returns nil, that means it doesn't specify
-  the indentation.
 
-This function also returns nil meaning don't specify the indentation."
+* a function to call that returns the indentation (or nil).
+  `lisp-indent-function' calls this function with the same two arguments
+  that it itself received.
+
+This function returns either the indentation to use, or nil if the
+Lisp function does not specify a special indentation."
   (let ((normal-indent (current-column)))
     (goto-char (1+ (elt state 1)))
     (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
@@ -1173,32 +1232,17 @@ This function also returns nil meaning don't specify the indentation."
 (put 'prog1 'lisp-indent-function 1)
 (put 'prog2 'lisp-indent-function 2)
 (put 'save-excursion 'lisp-indent-function 0)
-(put 'save-window-excursion 'lisp-indent-function 0)
-(put 'save-selected-window 'lisp-indent-function 0)
 (put 'save-restriction 'lisp-indent-function 0)
 (put 'save-match-data 'lisp-indent-function 0)
 (put 'save-current-buffer 'lisp-indent-function 0)
-(put 'with-current-buffer 'lisp-indent-function 1)
-(put 'combine-after-change-calls 'lisp-indent-function 0)
-(put 'with-output-to-string 'lisp-indent-function 0)
-(put 'with-temp-file 'lisp-indent-function 1)
-(put 'with-temp-buffer 'lisp-indent-function 0)
-(put 'with-temp-message 'lisp-indent-function 1)
-(put 'with-syntax-table 'lisp-indent-function 1)
 (put 'let 'lisp-indent-function 1)
 (put 'let* 'lisp-indent-function 1)
 (put 'while 'lisp-indent-function 1)
 (put 'if 'lisp-indent-function 2)
-(put 'read-if 'lisp-indent-function 2)
 (put 'catch 'lisp-indent-function 1)
 (put 'condition-case 'lisp-indent-function 2)
 (put 'unwind-protect 'lisp-indent-function 1)
 (put 'with-output-to-temp-buffer 'lisp-indent-function 1)
-(put 'eval-after-load 'lisp-indent-function 1)
-(put 'dolist 'lisp-indent-function 1)
-(put 'dotimes 'lisp-indent-function 1)
-(put 'when 'lisp-indent-function 1)
-(put 'unless 'lisp-indent-function 1)
 
 (defun indent-sexp (&optional endpos)
   "Indent each line of the list starting just after point.
@@ -1303,16 +1347,6 @@ ENDPOS is encountered."
            (setq outer-loop-done (= (point) last-point))
            (setq last-point (point)))))))
 
-(defun lisp-indent-region (start end)
-  "Indent every line whose first char is between START and END inclusive."
-  (save-excursion
-    (let ((endmark (copy-marker end)))
-      (goto-char start)
-      (and (bolp) (not (eolp))
-          (lisp-indent-line))
-      (indent-sexp endmark)
-      (set-marker endmark nil))))
-
 (defun indent-pp-sexp (&optional arg)
   "Indent each line of the list starting just after point, or prettyprint it.
 A prefix argument specifies pretty-printing."
@@ -1420,5 +1454,4 @@ means don't indent that line."
 
 (provide 'lisp-mode)
 
-;; arch-tag: 414c7f93-c245-4b77-8ed5-ed05ef7ff1bf
 ;;; lisp-mode.el ends here