| 1 | ;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands |
| 2 | |
| 3 | ;; Copyright (C) 1985-1986, 1999-2011 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Maintainer: FSF |
| 6 | ;; Keywords: lisp, languages |
| 7 | ;; Package: emacs |
| 8 | |
| 9 | ;; This file is part of GNU Emacs. |
| 10 | |
| 11 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
| 12 | ;; it under the terms of the GNU General Public License as published by |
| 13 | ;; the Free Software Foundation, either version 3 of the License, or |
| 14 | ;; (at your option) any later version. |
| 15 | |
| 16 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | ;; GNU General Public License for more details. |
| 20 | |
| 21 | ;; You should have received a copy of the GNU General Public License |
| 22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
| 23 | |
| 24 | ;;; Commentary: |
| 25 | |
| 26 | ;; The base major mode for editing Lisp code (used also for Emacs Lisp). |
| 27 | ;; This mode is documented in the Emacs manual. |
| 28 | |
| 29 | ;;; Code: |
| 30 | |
| 31 | (defvar font-lock-comment-face) |
| 32 | (defvar font-lock-doc-face) |
| 33 | (defvar font-lock-keywords-case-fold-search) |
| 34 | (defvar font-lock-string-face) |
| 35 | |
| 36 | (defvar lisp-mode-abbrev-table nil) |
| 37 | |
| 38 | (define-abbrev-table 'lisp-mode-abbrev-table ()) |
| 39 | |
| 40 | (defvar emacs-lisp-mode-syntax-table |
| 41 | (let ((table (make-syntax-table))) |
| 42 | (let ((i 0)) |
| 43 | (while (< i ?0) |
| 44 | (modify-syntax-entry i "_ " table) |
| 45 | (setq i (1+ i))) |
| 46 | (setq i (1+ ?9)) |
| 47 | (while (< i ?A) |
| 48 | (modify-syntax-entry i "_ " table) |
| 49 | (setq i (1+ i))) |
| 50 | (setq i (1+ ?Z)) |
| 51 | (while (< i ?a) |
| 52 | (modify-syntax-entry i "_ " table) |
| 53 | (setq i (1+ i))) |
| 54 | (setq i (1+ ?z)) |
| 55 | (while (< i 128) |
| 56 | (modify-syntax-entry i "_ " table) |
| 57 | (setq i (1+ i))) |
| 58 | (modify-syntax-entry ?\s " " table) |
| 59 | ;; Non-break space acts as whitespace. |
| 60 | (modify-syntax-entry ?\x8a0 " " table) |
| 61 | (modify-syntax-entry ?\t " " table) |
| 62 | (modify-syntax-entry ?\f " " table) |
| 63 | (modify-syntax-entry ?\n "> " table) |
| 64 | ;; This is probably obsolete since nowadays such features use overlays. |
| 65 | ;; ;; Give CR the same syntax as newline, for selective-display. |
| 66 | ;; (modify-syntax-entry ?\^m "> " table) |
| 67 | (modify-syntax-entry ?\; "< " table) |
| 68 | (modify-syntax-entry ?` "' " table) |
| 69 | (modify-syntax-entry ?' "' " table) |
| 70 | (modify-syntax-entry ?, "' " table) |
| 71 | (modify-syntax-entry ?@ "' " table) |
| 72 | ;; Used to be singlequote; changed for flonums. |
| 73 | (modify-syntax-entry ?. "_ " table) |
| 74 | (modify-syntax-entry ?# "' " table) |
| 75 | (modify-syntax-entry ?\" "\" " table) |
| 76 | (modify-syntax-entry ?\\ "\\ " table) |
| 77 | (modify-syntax-entry ?\( "() " table) |
| 78 | (modify-syntax-entry ?\) ")( " table) |
| 79 | (modify-syntax-entry ?\[ "(] " table) |
| 80 | (modify-syntax-entry ?\] ")[ " table)) |
| 81 | table) |
| 82 | "Syntax table used in `emacs-lisp-mode'.") |
| 83 | |
| 84 | (defvar lisp-mode-syntax-table |
| 85 | (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table))) |
| 86 | (modify-syntax-entry ?\[ "_ " table) |
| 87 | (modify-syntax-entry ?\] "_ " table) |
| 88 | (modify-syntax-entry ?# "' 14" table) |
| 89 | (modify-syntax-entry ?| "\" 23bn" table) |
| 90 | table) |
| 91 | "Syntax table used in `lisp-mode'.") |
| 92 | |
| 93 | (defvar lisp-imenu-generic-expression |
| 94 | (list |
| 95 | (list nil |
| 96 | (purecopy (concat "^\\s-*(" |
| 97 | (eval-when-compile |
| 98 | (regexp-opt |
| 99 | '("defun" "defun*" "defsubst" "defmacro" |
| 100 | "defadvice" "define-skeleton" |
| 101 | "define-minor-mode" "define-global-minor-mode" |
| 102 | "define-globalized-minor-mode" |
| 103 | "define-derived-mode" "define-generic-mode" |
| 104 | "define-compiler-macro" "define-modify-macro" |
| 105 | "defsetf" "define-setf-expander" |
| 106 | "define-method-combination" |
| 107 | "defgeneric" "defmethod") t)) |
| 108 | "\\s-+\\(\\(\\sw\\|\\s_\\)+\\)")) |
| 109 | 2) |
| 110 | (list (purecopy "Variables") |
| 111 | (purecopy (concat "^\\s-*(" |
| 112 | (eval-when-compile |
| 113 | (regexp-opt |
| 114 | '("defvar" "defconst" "defconstant" "defcustom" |
| 115 | "defparameter" "define-symbol-macro") t)) |
| 116 | "\\s-+\\(\\(\\sw\\|\\s_\\)+\\)")) |
| 117 | 2) |
| 118 | (list (purecopy "Types") |
| 119 | (purecopy (concat "^\\s-*(" |
| 120 | (eval-when-compile |
| 121 | (regexp-opt |
| 122 | '("defgroup" "deftheme" "deftype" "defstruct" |
| 123 | "defclass" "define-condition" "define-widget" |
| 124 | "defface" "defpackage") t)) |
| 125 | "\\s-+'?\\(\\(\\sw\\|\\s_\\)+\\)")) |
| 126 | 2)) |
| 127 | |
| 128 | "Imenu generic expression for Lisp mode. See `imenu-generic-expression'.") |
| 129 | |
| 130 | ;; This was originally in autoload.el and is still used there. |
| 131 | (put 'autoload 'doc-string-elt 3) |
| 132 | (put 'defun 'doc-string-elt 3) |
| 133 | (put 'defun* 'doc-string-elt 3) |
| 134 | (put 'defvar 'doc-string-elt 3) |
| 135 | (put 'defcustom 'doc-string-elt 3) |
| 136 | (put 'deftheme 'doc-string-elt 2) |
| 137 | (put 'deftype 'doc-string-elt 3) |
| 138 | (put 'defconst 'doc-string-elt 3) |
| 139 | (put 'defmacro 'doc-string-elt 3) |
| 140 | (put 'defmacro* 'doc-string-elt 3) |
| 141 | (put 'defsubst 'doc-string-elt 3) |
| 142 | (put 'defstruct 'doc-string-elt 2) |
| 143 | (put 'define-skeleton 'doc-string-elt 2) |
| 144 | (put 'define-derived-mode 'doc-string-elt 4) |
| 145 | (put 'define-compilation-mode 'doc-string-elt 3) |
| 146 | (put 'easy-mmode-define-minor-mode 'doc-string-elt 2) |
| 147 | (put 'define-minor-mode 'doc-string-elt 2) |
| 148 | (put 'easy-mmode-define-global-mode 'doc-string-elt 2) |
| 149 | (put 'define-global-minor-mode 'doc-string-elt 2) |
| 150 | (put 'define-globalized-minor-mode 'doc-string-elt 2) |
| 151 | (put 'define-generic-mode 'doc-string-elt 7) |
| 152 | (put 'define-ibuffer-filter 'doc-string-elt 2) |
| 153 | (put 'define-ibuffer-op 'doc-string-elt 3) |
| 154 | (put 'define-ibuffer-sorter 'doc-string-elt 2) |
| 155 | (put 'lambda 'doc-string-elt 2) |
| 156 | (put 'defalias 'doc-string-elt 3) |
| 157 | (put 'defvaralias 'doc-string-elt 3) |
| 158 | (put 'define-category 'doc-string-elt 2) |
| 159 | (put 'define-overloadable-function 'doc-string-elt 3) |
| 160 | |
| 161 | (defvar lisp-doc-string-elt-property 'doc-string-elt |
| 162 | "The symbol property that holds the docstring position info.") |
| 163 | |
| 164 | (defun lisp-font-lock-syntactic-face-function (state) |
| 165 | (if (nth 3 state) |
| 166 | ;; This might be a (doc)string or a |...| symbol. |
| 167 | (let ((startpos (nth 8 state))) |
| 168 | (if (eq (char-after startpos) ?|) |
| 169 | ;; This is not a string, but a |...| symbol. |
| 170 | nil |
| 171 | (let* ((listbeg (nth 1 state)) |
| 172 | (firstsym (and listbeg |
| 173 | (save-excursion |
| 174 | (goto-char listbeg) |
| 175 | (and (looking-at "([ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)") |
| 176 | (match-string 1))))) |
| 177 | (docelt (and firstsym (get (intern-soft firstsym) |
| 178 | lisp-doc-string-elt-property)))) |
| 179 | (if (and docelt |
| 180 | ;; It's a string in a form that can have a docstring. |
| 181 | ;; Check whether it's in docstring position. |
| 182 | (save-excursion |
| 183 | (when (functionp docelt) |
| 184 | (goto-char (match-end 1)) |
| 185 | (setq docelt (funcall docelt))) |
| 186 | (goto-char listbeg) |
| 187 | (forward-char 1) |
| 188 | (condition-case nil |
| 189 | (while (and (> docelt 0) (< (point) startpos) |
| 190 | (progn (forward-sexp 1) t)) |
| 191 | (setq docelt (1- docelt))) |
| 192 | (error nil)) |
| 193 | (and (zerop docelt) (<= (point) startpos) |
| 194 | (progn (forward-comment (point-max)) t) |
| 195 | (= (point) (nth 8 state))))) |
| 196 | font-lock-doc-face |
| 197 | font-lock-string-face)))) |
| 198 | font-lock-comment-face)) |
| 199 | |
| 200 | (defun lisp-mode-variables (&optional lisp-syntax keywords-case-insensitive) |
| 201 | "Common initialization routine for lisp modes. |
| 202 | The LISP-SYNTAX argument is used by code in inf-lisp.el and is |
| 203 | \(uselessly) passed from pp.el, chistory.el, gnus-kill.el and |
| 204 | score-mode.el. KEYWORDS-CASE-INSENSITIVE non-nil means that for |
| 205 | font-lock keywords will not be case sensitive." |
| 206 | (when lisp-syntax |
| 207 | (set-syntax-table lisp-mode-syntax-table)) |
| 208 | (setq local-abbrev-table lisp-mode-abbrev-table) |
| 209 | (make-local-variable 'paragraph-ignore-fill-prefix) |
| 210 | (setq paragraph-ignore-fill-prefix t) |
| 211 | (make-local-variable 'fill-paragraph-function) |
| 212 | (setq fill-paragraph-function 'lisp-fill-paragraph) |
| 213 | ;; Adaptive fill mode gets the fill wrong for a one-line paragraph made of |
| 214 | ;; a single docstring. Let's fix it here. |
| 215 | (set (make-local-variable 'adaptive-fill-function) |
| 216 | (lambda () (if (looking-at "\\s-+\"[^\n\"]+\"\\s-*$") ""))) |
| 217 | ;; Adaptive fill mode gets in the way of auto-fill, |
| 218 | ;; and should make no difference for explicit fill |
| 219 | ;; because lisp-fill-paragraph should do the job. |
| 220 | ;; I believe that newcomment's auto-fill code properly deals with it -stef |
| 221 | ;;(set (make-local-variable 'adaptive-fill-mode) nil) |
| 222 | (make-local-variable 'indent-line-function) |
| 223 | (setq indent-line-function 'lisp-indent-line) |
| 224 | (make-local-variable 'outline-regexp) |
| 225 | (setq outline-regexp ";;;\\(;* [^ \t\n]\\|###autoload\\)\\|(") |
| 226 | (make-local-variable 'outline-level) |
| 227 | (setq outline-level 'lisp-outline-level) |
| 228 | (make-local-variable 'comment-start) |
| 229 | (setq comment-start ";") |
| 230 | (make-local-variable 'comment-start-skip) |
| 231 | ;; Look within the line for a ; following an even number of backslashes |
| 232 | ;; after either a non-backslash or the line beginning. |
| 233 | (setq comment-start-skip "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+ *") |
| 234 | (make-local-variable 'font-lock-comment-start-skip) |
| 235 | ;; Font lock mode uses this only when it KNOWS a comment is starting. |
| 236 | (setq font-lock-comment-start-skip ";+ *") |
| 237 | (make-local-variable 'comment-add) |
| 238 | (setq comment-add 1) ;default to `;;' in comment-region |
| 239 | (make-local-variable 'comment-column) |
| 240 | (setq comment-column 40) |
| 241 | ;; Don't get confused by `;' in doc strings when paragraph-filling. |
| 242 | (set (make-local-variable 'comment-use-global-state) t) |
| 243 | (make-local-variable 'imenu-generic-expression) |
| 244 | (setq imenu-generic-expression lisp-imenu-generic-expression) |
| 245 | (make-local-variable 'multibyte-syntax-as-symbol) |
| 246 | (setq multibyte-syntax-as-symbol t) |
| 247 | (set (make-local-variable 'syntax-begin-function) 'beginning-of-defun) |
| 248 | (setq font-lock-defaults |
| 249 | `((lisp-font-lock-keywords |
| 250 | lisp-font-lock-keywords-1 lisp-font-lock-keywords-2) |
| 251 | nil ,keywords-case-insensitive (("+-*/.<>=!?$%_&~^:@" . "w")) nil |
| 252 | (font-lock-mark-block-function . mark-defun) |
| 253 | (font-lock-syntactic-face-function |
| 254 | . lisp-font-lock-syntactic-face-function)))) |
| 255 | |
| 256 | (defun lisp-outline-level () |
| 257 | "Lisp mode `outline-level' function." |
| 258 | (let ((len (- (match-end 0) (match-beginning 0)))) |
| 259 | (if (looking-at "(\\|;;;###autoload") |
| 260 | 1000 |
| 261 | len))) |
| 262 | |
| 263 | (defvar lisp-mode-shared-map |
| 264 | (let ((map (make-sparse-keymap))) |
| 265 | (define-key map "\e\C-q" 'indent-sexp) |
| 266 | (define-key map "\177" 'backward-delete-char-untabify) |
| 267 | ;; This gets in the way when viewing a Lisp file in view-mode. As |
| 268 | ;; long as [backspace] is mapped into DEL via the |
| 269 | ;; function-key-map, this should remain disabled!! |
| 270 | ;;;(define-key map [backspace] 'backward-delete-char-untabify) |
| 271 | map) |
| 272 | "Keymap for commands shared by all sorts of Lisp modes.") |
| 273 | |
| 274 | (defvar emacs-lisp-mode-map |
| 275 | (let ((map (make-sparse-keymap "Emacs-Lisp")) |
| 276 | (menu-map (make-sparse-keymap "Emacs-Lisp")) |
| 277 | (lint-map (make-sparse-keymap)) |
| 278 | (prof-map (make-sparse-keymap)) |
| 279 | (tracing-map (make-sparse-keymap))) |
| 280 | (set-keymap-parent map lisp-mode-shared-map) |
| 281 | (define-key map "\e\t" 'completion-at-point) |
| 282 | (define-key map "\e\C-x" 'eval-defun) |
| 283 | (define-key map "\e\C-q" 'indent-pp-sexp) |
| 284 | (define-key map [menu-bar emacs-lisp] (cons (purecopy "Emacs-Lisp") menu-map)) |
| 285 | (define-key menu-map [eldoc] |
| 286 | `(menu-item ,(purecopy "Auto-Display Documentation Strings") eldoc-mode |
| 287 | :button (:toggle . (bound-and-true-p eldoc-mode)) |
| 288 | :help ,(purecopy "Display the documentation string for the item under cursor"))) |
| 289 | (define-key menu-map [checkdoc] |
| 290 | `(menu-item ,(purecopy "Check Documentation Strings") checkdoc |
| 291 | :help ,(purecopy "Check documentation strings for style requirements"))) |
| 292 | (define-key menu-map [re-builder] |
| 293 | `(menu-item ,(purecopy "Construct Regexp") re-builder |
| 294 | :help ,(purecopy "Construct a regexp interactively"))) |
| 295 | (define-key menu-map [tracing] (cons (purecopy "Tracing") tracing-map)) |
| 296 | (define-key tracing-map [tr-a] |
| 297 | `(menu-item ,(purecopy "Untrace All") untrace-all |
| 298 | :help ,(purecopy "Untrace all currently traced functions"))) |
| 299 | (define-key tracing-map [tr-uf] |
| 300 | `(menu-item ,(purecopy "Untrace function...") untrace-function |
| 301 | :help ,(purecopy "Untrace function, and possibly activate all remaining advice"))) |
| 302 | (define-key tracing-map [tr-sep] menu-bar-separator) |
| 303 | (define-key tracing-map [tr-q] |
| 304 | `(menu-item ,(purecopy "Trace Function Quietly...") trace-function-background |
| 305 | :help ,(purecopy "Trace the function with trace output going quietly to a buffer"))) |
| 306 | (define-key tracing-map [tr-f] |
| 307 | `(menu-item ,(purecopy "Trace Function...") trace-function |
| 308 | :help ,(purecopy "Trace the function given as an argument"))) |
| 309 | (define-key menu-map [profiling] (cons (purecopy "Profiling") prof-map)) |
| 310 | (define-key prof-map [prof-restall] |
| 311 | `(menu-item ,(purecopy "Remove Instrumentation for All Functions") elp-restore-all |
| 312 | :help ,(purecopy "Restore the original definitions of all functions being profiled"))) |
| 313 | (define-key prof-map [prof-restfunc] |
| 314 | `(menu-item ,(purecopy "Remove Instrumentation for Function...") elp-restore-function |
| 315 | :help ,(purecopy "Restore an instrumented function to its original definition"))) |
| 316 | |
| 317 | (define-key prof-map [sep-rem] menu-bar-separator) |
| 318 | (define-key prof-map [prof-resall] |
| 319 | `(menu-item ,(purecopy "Reset Counters for All Functions") elp-reset-all |
| 320 | :help ,(purecopy "Reset the profiling information for all functions being profiled"))) |
| 321 | (define-key prof-map [prof-resfunc] |
| 322 | `(menu-item ,(purecopy "Reset Counters for Function...") elp-reset-function |
| 323 | :help ,(purecopy "Reset the profiling information for a function"))) |
| 324 | (define-key prof-map [prof-res] |
| 325 | `(menu-item ,(purecopy "Show Profiling Results") elp-results |
| 326 | :help ,(purecopy "Display current profiling results"))) |
| 327 | (define-key prof-map [prof-pack] |
| 328 | `(menu-item ,(purecopy "Instrument Package...") elp-instrument-package |
| 329 | :help ,(purecopy "Instrument for profiling all function that start with a prefix"))) |
| 330 | (define-key prof-map [prof-func] |
| 331 | `(menu-item ,(purecopy "Instrument Function...") elp-instrument-function |
| 332 | :help ,(purecopy "Instrument a function for profiling"))) |
| 333 | (define-key menu-map [lint] (cons (purecopy "Linting") lint-map)) |
| 334 | (define-key lint-map [lint-di] |
| 335 | `(menu-item ,(purecopy "Lint Directory...") elint-directory |
| 336 | :help ,(purecopy "Lint a directory"))) |
| 337 | (define-key lint-map [lint-f] |
| 338 | `(menu-item ,(purecopy "Lint File...") elint-file |
| 339 | :help ,(purecopy "Lint a file"))) |
| 340 | (define-key lint-map [lint-b] |
| 341 | `(menu-item ,(purecopy "Lint Buffer") elint-current-buffer |
| 342 | :help ,(purecopy "Lint the current buffer"))) |
| 343 | (define-key lint-map [lint-d] |
| 344 | `(menu-item ,(purecopy "Lint Defun") elint-defun |
| 345 | :help ,(purecopy "Lint the function at point"))) |
| 346 | (define-key menu-map [edebug-defun] |
| 347 | `(menu-item ,(purecopy "Instrument Function for Debugging") edebug-defun |
| 348 | :help ,(purecopy "Evaluate the top level form point is in, stepping through with Edebug") |
| 349 | :keys ,(purecopy "C-u C-M-x"))) |
| 350 | (define-key menu-map [separator-byte] menu-bar-separator) |
| 351 | (define-key menu-map [disas] |
| 352 | `(menu-item ,(purecopy "Disassemble Byte Compiled Object...") disassemble |
| 353 | :help ,(purecopy "Print disassembled code for OBJECT in a buffer"))) |
| 354 | (define-key menu-map [byte-recompile] |
| 355 | `(menu-item ,(purecopy "Byte-recompile Directory...") byte-recompile-directory |
| 356 | :help ,(purecopy "Recompile every `.el' file in DIRECTORY that needs recompilation"))) |
| 357 | (define-key menu-map [emacs-byte-compile-and-load] |
| 358 | `(menu-item ,(purecopy "Byte-compile and Load") emacs-lisp-byte-compile-and-load |
| 359 | :help ,(purecopy "Byte-compile the current file (if it has changed), then load compiled code"))) |
| 360 | (define-key menu-map [byte-compile] |
| 361 | `(menu-item ,(purecopy "Byte-compile this File") emacs-lisp-byte-compile |
| 362 | :help ,(purecopy "Byte compile the file containing the current buffer"))) |
| 363 | (define-key menu-map [separator-eval] menu-bar-separator) |
| 364 | (define-key menu-map [ielm] |
| 365 | `(menu-item ,(purecopy "Interactive Expression Evaluation") ielm |
| 366 | :help ,(purecopy "Interactively evaluate Emacs Lisp expressions"))) |
| 367 | (define-key menu-map [eval-buffer] |
| 368 | `(menu-item ,(purecopy "Evaluate Buffer") eval-buffer |
| 369 | :help ,(purecopy "Execute the current buffer as Lisp code"))) |
| 370 | (define-key menu-map [eval-region] |
| 371 | `(menu-item ,(purecopy "Evaluate Region") eval-region |
| 372 | :help ,(purecopy "Execute the region as Lisp code") |
| 373 | :enable mark-active)) |
| 374 | (define-key menu-map [eval-sexp] |
| 375 | `(menu-item ,(purecopy "Evaluate Last S-expression") eval-last-sexp |
| 376 | :help ,(purecopy "Evaluate sexp before point; print value in minibuffer"))) |
| 377 | (define-key menu-map [separator-format] menu-bar-separator) |
| 378 | (define-key menu-map [comment-region] |
| 379 | `(menu-item ,(purecopy "Comment Out Region") comment-region |
| 380 | :help ,(purecopy "Comment or uncomment each line in the region") |
| 381 | :enable mark-active)) |
| 382 | (define-key menu-map [indent-region] |
| 383 | `(menu-item ,(purecopy "Indent Region") indent-region |
| 384 | :help ,(purecopy "Indent each nonblank line in the region") |
| 385 | :enable mark-active)) |
| 386 | (define-key menu-map [indent-line] |
| 387 | `(menu-item ,(purecopy "Indent Line") lisp-indent-line)) |
| 388 | map) |
| 389 | "Keymap for Emacs Lisp mode. |
| 390 | All commands in `lisp-mode-shared-map' are inherited by this map.") |
| 391 | |
| 392 | (defun emacs-lisp-byte-compile () |
| 393 | "Byte compile the file containing the current buffer." |
| 394 | (interactive) |
| 395 | (if buffer-file-name |
| 396 | (byte-compile-file buffer-file-name) |
| 397 | (error "The buffer must be saved in a file first"))) |
| 398 | |
| 399 | (defun emacs-lisp-byte-compile-and-load () |
| 400 | "Byte-compile the current file (if it has changed), then load compiled code." |
| 401 | (interactive) |
| 402 | (or buffer-file-name |
| 403 | (error "The buffer must be saved in a file first")) |
| 404 | (require 'bytecomp) |
| 405 | ;; Recompile if file or buffer has changed since last compilation. |
| 406 | (if (and (buffer-modified-p) |
| 407 | (y-or-n-p (format "Save buffer %s first? " (buffer-name)))) |
| 408 | (save-buffer)) |
| 409 | (byte-recompile-file buffer-file-name nil 0 t)) |
| 410 | |
| 411 | (defcustom emacs-lisp-mode-hook nil |
| 412 | "Hook run when entering Emacs Lisp mode." |
| 413 | :options '(turn-on-eldoc-mode imenu-add-menubar-index checkdoc-minor-mode) |
| 414 | :type 'hook |
| 415 | :group 'lisp) |
| 416 | |
| 417 | (defcustom lisp-mode-hook nil |
| 418 | "Hook run when entering Lisp mode." |
| 419 | :options '(imenu-add-menubar-index) |
| 420 | :type 'hook |
| 421 | :group 'lisp) |
| 422 | |
| 423 | (defcustom lisp-interaction-mode-hook nil |
| 424 | "Hook run when entering Lisp Interaction mode." |
| 425 | :options '(turn-on-eldoc-mode) |
| 426 | :type 'hook |
| 427 | :group 'lisp) |
| 428 | |
| 429 | (define-derived-mode emacs-lisp-mode prog-mode "Emacs-Lisp" |
| 430 | "Major mode for editing Lisp code to run in Emacs. |
| 431 | Commands: |
| 432 | Delete converts tabs to spaces as it moves back. |
| 433 | Blank lines separate paragraphs. Semicolons start comments. |
| 434 | |
| 435 | \\{emacs-lisp-mode-map} |
| 436 | Entry to this mode calls the value of `emacs-lisp-mode-hook' |
| 437 | if that value is non-nil." |
| 438 | :group 'lisp |
| 439 | (lisp-mode-variables) |
| 440 | (setq imenu-case-fold-search nil) |
| 441 | (add-hook 'completion-at-point-functions |
| 442 | 'lisp-completion-at-point nil 'local)) |
| 443 | |
| 444 | (defvar lisp-mode-map |
| 445 | (let ((map (make-sparse-keymap)) |
| 446 | (menu-map (make-sparse-keymap "Lisp"))) |
| 447 | (set-keymap-parent map lisp-mode-shared-map) |
| 448 | (define-key map "\e\C-x" 'lisp-eval-defun) |
| 449 | (define-key map "\C-c\C-z" 'run-lisp) |
| 450 | (define-key map [menu-bar lisp] (cons (purecopy "Lisp") menu-map)) |
| 451 | (define-key menu-map [run-lisp] |
| 452 | `(menu-item ,(purecopy "Run inferior Lisp") run-lisp |
| 453 | :help ,(purecopy "Run an inferior Lisp process, input and output via buffer `*inferior-lisp*'"))) |
| 454 | (define-key menu-map [ev-def] |
| 455 | `(menu-item ,(purecopy "Eval defun") lisp-eval-defun |
| 456 | :help ,(purecopy "Send the current defun to the Lisp process made by M-x run-lisp"))) |
| 457 | (define-key menu-map [ind-sexp] |
| 458 | `(menu-item ,(purecopy "Indent sexp") indent-sexp |
| 459 | :help ,(purecopy "Indent each line of the list starting just after point"))) |
| 460 | map) |
| 461 | "Keymap for ordinary Lisp mode. |
| 462 | All commands in `lisp-mode-shared-map' are inherited by this map.") |
| 463 | |
| 464 | (define-derived-mode lisp-mode prog-mode "Lisp" |
| 465 | "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp. |
| 466 | Commands: |
| 467 | Delete converts tabs to spaces as it moves back. |
| 468 | Blank lines separate paragraphs. Semicolons start comments. |
| 469 | |
| 470 | \\{lisp-mode-map} |
| 471 | Note that `run-lisp' may be used either to start an inferior Lisp job |
| 472 | or to switch back to an existing one. |
| 473 | |
| 474 | Entry to this mode calls the value of `lisp-mode-hook' |
| 475 | if that value is non-nil." |
| 476 | (lisp-mode-variables nil t) |
| 477 | (set (make-local-variable 'find-tag-default-function) 'lisp-find-tag-default) |
| 478 | (make-local-variable 'comment-start-skip) |
| 479 | (setq comment-start-skip |
| 480 | "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *") |
| 481 | (setq imenu-case-fold-search t)) |
| 482 | |
| 483 | (defun lisp-find-tag-default () |
| 484 | (let ((default (find-tag-default))) |
| 485 | (when (stringp default) |
| 486 | (if (string-match ":+" default) |
| 487 | (substring default (match-end 0)) |
| 488 | default)))) |
| 489 | |
| 490 | ;; Used in old LispM code. |
| 491 | (defalias 'common-lisp-mode 'lisp-mode) |
| 492 | |
| 493 | ;; This will do unless inf-lisp.el is loaded. |
| 494 | (defun lisp-eval-defun (&optional and-go) |
| 495 | "Send the current defun to the Lisp process made by \\[run-lisp]." |
| 496 | (interactive) |
| 497 | (error "Process lisp does not exist")) |
| 498 | |
| 499 | (defvar lisp-interaction-mode-map |
| 500 | (let ((map (make-sparse-keymap)) |
| 501 | (menu-map (make-sparse-keymap "Lisp-Interaction"))) |
| 502 | (set-keymap-parent map lisp-mode-shared-map) |
| 503 | (define-key map "\e\C-x" 'eval-defun) |
| 504 | (define-key map "\e\C-q" 'indent-pp-sexp) |
| 505 | (define-key map "\e\t" 'completion-at-point) |
| 506 | (define-key map "\n" 'eval-print-last-sexp) |
| 507 | (define-key map [menu-bar lisp-interaction] (cons (purecopy "Lisp-Interaction") menu-map)) |
| 508 | (define-key menu-map [eval-defun] |
| 509 | `(menu-item ,(purecopy "Evaluate Defun") eval-defun |
| 510 | :help ,(purecopy "Evaluate the top-level form containing point, or after point"))) |
| 511 | (define-key menu-map [eval-print-last-sexp] |
| 512 | `(menu-item ,(purecopy "Evaluate and print") eval-print-last-sexp |
| 513 | :help ,(purecopy "Evaluate sexp before point; print value into current buffer"))) |
| 514 | (define-key menu-map [edebug-defun-lisp-interaction] |
| 515 | `(menu-item ,(purecopy "Instrument Function for Debugging") edebug-defun |
| 516 | :help ,(purecopy "Evaluate the top level form point is in, stepping through with Edebug") |
| 517 | :keys ,(purecopy "C-u C-M-x"))) |
| 518 | (define-key menu-map [indent-pp-sexp] |
| 519 | `(menu-item ,(purecopy "Indent or Pretty-Print") indent-pp-sexp |
| 520 | :help ,(purecopy "Indent each line of the list starting just after point, or prettyprint it"))) |
| 521 | (define-key menu-map [complete-symbol] |
| 522 | `(menu-item ,(purecopy "Complete Lisp Symbol") completion-at-point |
| 523 | :help ,(purecopy "Perform completion on Lisp symbol preceding point"))) |
| 524 | map) |
| 525 | "Keymap for Lisp Interaction mode. |
| 526 | All commands in `lisp-mode-shared-map' are inherited by this map.") |
| 527 | |
| 528 | (defvar lisp-interaction-mode-abbrev-table lisp-mode-abbrev-table) |
| 529 | (define-derived-mode lisp-interaction-mode emacs-lisp-mode "Lisp Interaction" |
| 530 | "Major mode for typing and evaluating Lisp forms. |
| 531 | Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression |
| 532 | before point, and prints its value into the buffer, advancing point. |
| 533 | Note that printing is controlled by `eval-expression-print-length' |
| 534 | and `eval-expression-print-level'. |
| 535 | |
| 536 | Commands: |
| 537 | Delete converts tabs to spaces as it moves back. |
| 538 | Paragraphs are separated only by blank lines. |
| 539 | Semicolons start comments. |
| 540 | |
| 541 | \\{lisp-interaction-mode-map} |
| 542 | Entry to this mode calls the value of `lisp-interaction-mode-hook' |
| 543 | if that value is non-nil.") |
| 544 | |
| 545 | (defun eval-print-last-sexp () |
| 546 | "Evaluate sexp before point; print value into current buffer. |
| 547 | |
| 548 | If `eval-expression-debug-on-error' is non-nil, which is the default, |
| 549 | this command arranges for all errors to enter the debugger. |
| 550 | |
| 551 | Note that printing the result is controlled by the variables |
| 552 | `eval-expression-print-length' and `eval-expression-print-level', |
| 553 | which see." |
| 554 | (interactive) |
| 555 | (let ((standard-output (current-buffer))) |
| 556 | (terpri) |
| 557 | (eval-last-sexp t) |
| 558 | (terpri))) |
| 559 | |
| 560 | |
| 561 | (defun last-sexp-setup-props (beg end value alt1 alt2) |
| 562 | "Set up text properties for the output of `eval-last-sexp-1'. |
| 563 | BEG and END are the start and end of the output in current-buffer. |
| 564 | VALUE is the Lisp value printed, ALT1 and ALT2 are strings for the |
| 565 | alternative printed representations that can be displayed." |
| 566 | (let ((map (make-sparse-keymap))) |
| 567 | (define-key map "\C-m" 'last-sexp-toggle-display) |
| 568 | (define-key map [down-mouse-2] 'mouse-set-point) |
| 569 | (define-key map [mouse-2] 'last-sexp-toggle-display) |
| 570 | (add-text-properties |
| 571 | beg end |
| 572 | `(printed-value (,value ,alt1 ,alt2) |
| 573 | mouse-face highlight |
| 574 | keymap ,map |
| 575 | help-echo "RET, mouse-2: toggle abbreviated display" |
| 576 | rear-nonsticky (mouse-face keymap help-echo |
| 577 | printed-value))))) |
| 578 | |
| 579 | |
| 580 | (defun last-sexp-toggle-display (&optional arg) |
| 581 | "Toggle between abbreviated and unabbreviated printed representations." |
| 582 | (interactive "P") |
| 583 | (save-restriction |
| 584 | (widen) |
| 585 | (let ((value (get-text-property (point) 'printed-value))) |
| 586 | (when value |
| 587 | (let ((beg (or (previous-single-property-change (min (point-max) (1+ (point))) |
| 588 | 'printed-value) |
| 589 | (point))) |
| 590 | (end (or (next-single-char-property-change (point) 'printed-value) (point))) |
| 591 | (standard-output (current-buffer)) |
| 592 | (point (point))) |
| 593 | (delete-region beg end) |
| 594 | (insert (nth 1 value)) |
| 595 | (or (= beg point) |
| 596 | (setq point (1- (point)))) |
| 597 | (last-sexp-setup-props beg (point) |
| 598 | (nth 0 value) |
| 599 | (nth 2 value) |
| 600 | (nth 1 value)) |
| 601 | (goto-char (min (point-max) point))))))) |
| 602 | |
| 603 | (defun prin1-char (char) |
| 604 | "Return a string representing CHAR as a character rather than as an integer. |
| 605 | If CHAR is not a character, return nil." |
| 606 | (and (integerp char) |
| 607 | (eventp char) |
| 608 | (let ((c (event-basic-type char)) |
| 609 | (mods (event-modifiers char)) |
| 610 | string) |
| 611 | ;; Prevent ?A from turning into ?\S-a. |
| 612 | (if (and (memq 'shift mods) |
| 613 | (zerop (logand char ?\S-\^@)) |
| 614 | (not (let ((case-fold-search nil)) |
| 615 | (char-equal c (upcase c))))) |
| 616 | (setq c (upcase c) mods nil)) |
| 617 | ;; What string are we considering using? |
| 618 | (condition-case nil |
| 619 | (setq string |
| 620 | (concat |
| 621 | "?" |
| 622 | (mapconcat |
| 623 | (lambda (modif) |
| 624 | (cond ((eq modif 'super) "\\s-") |
| 625 | (t (string ?\\ (upcase (aref (symbol-name modif) 0)) ?-)))) |
| 626 | mods "") |
| 627 | (cond |
| 628 | ((memq c '(?\; ?\( ?\) ?\{ ?\} ?\[ ?\] ?\" ?\' ?\\)) (string ?\\ c)) |
| 629 | ((eq c 127) "\\C-?") |
| 630 | (t |
| 631 | (string c))))) |
| 632 | (error nil)) |
| 633 | ;; Verify the string reads a CHAR, not to some other character. |
| 634 | ;; If it doesn't, return nil instead. |
| 635 | (and string |
| 636 | (= (car (read-from-string string)) char) |
| 637 | string)))) |
| 638 | |
| 639 | |
| 640 | (defun preceding-sexp () |
| 641 | "Return sexp before the point." |
| 642 | (let ((opoint (point)) |
| 643 | ignore-quotes |
| 644 | expr) |
| 645 | (save-excursion |
| 646 | (with-syntax-table emacs-lisp-mode-syntax-table |
| 647 | ;; If this sexp appears to be enclosed in `...' |
| 648 | ;; then ignore the surrounding quotes. |
| 649 | (setq ignore-quotes |
| 650 | (or (eq (following-char) ?\') |
| 651 | (eq (preceding-char) ?\'))) |
| 652 | (forward-sexp -1) |
| 653 | ;; If we were after `?\e' (or similar case), |
| 654 | ;; use the whole thing, not just the `e'. |
| 655 | (when (eq (preceding-char) ?\\) |
| 656 | (forward-char -1) |
| 657 | (when (eq (preceding-char) ??) |
| 658 | (forward-char -1))) |
| 659 | |
| 660 | ;; Skip over hash table read syntax. |
| 661 | (and (> (point) (1+ (point-min))) |
| 662 | (looking-back "#s" (- (point) 2)) |
| 663 | (forward-char -2)) |
| 664 | |
| 665 | ;; Skip over `#N='s. |
| 666 | (when (eq (preceding-char) ?=) |
| 667 | (let (labeled-p) |
| 668 | (save-excursion |
| 669 | (skip-chars-backward "0-9#=") |
| 670 | (setq labeled-p (looking-at "\\(#[0-9]+=\\)+"))) |
| 671 | (when labeled-p |
| 672 | (forward-sexp -1)))) |
| 673 | |
| 674 | (save-restriction |
| 675 | ;; vladimir@cs.ualberta.ca 30-Jul-1997: skip ` in |
| 676 | ;; `variable' so that the value is returned, not the |
| 677 | ;; name |
| 678 | (if (and ignore-quotes |
| 679 | (eq (following-char) ?`)) |
| 680 | (forward-char)) |
| 681 | (narrow-to-region (point-min) opoint) |
| 682 | (setq expr (read (current-buffer))) |
| 683 | ;; If it's an (interactive ...) form, it's more |
| 684 | ;; useful to show how an interactive call would |
| 685 | ;; use it. |
| 686 | (and (consp expr) |
| 687 | (eq (car expr) 'interactive) |
| 688 | (setq expr |
| 689 | (list 'call-interactively |
| 690 | (list 'quote |
| 691 | (list 'lambda |
| 692 | '(&rest args) |
| 693 | expr |
| 694 | 'args))))) |
| 695 | expr))))) |
| 696 | |
| 697 | |
| 698 | (defun eval-last-sexp-1 (eval-last-sexp-arg-internal) |
| 699 | "Evaluate sexp before point; print value in minibuffer. |
| 700 | With argument, print output into current buffer." |
| 701 | (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t))) |
| 702 | (eval-last-sexp-print-value (eval (preceding-sexp))))) |
| 703 | |
| 704 | |
| 705 | (defun eval-last-sexp-print-value (value) |
| 706 | (let ((unabbreviated (let ((print-length nil) (print-level nil)) |
| 707 | (prin1-to-string value))) |
| 708 | (print-length eval-expression-print-length) |
| 709 | (print-level eval-expression-print-level) |
| 710 | (beg (point)) |
| 711 | end) |
| 712 | (prog1 |
| 713 | (prin1 value) |
| 714 | (let ((str (eval-expression-print-format value))) |
| 715 | (if str (princ str))) |
| 716 | (setq end (point)) |
| 717 | (when (and (bufferp standard-output) |
| 718 | (or (not (null print-length)) |
| 719 | (not (null print-level))) |
| 720 | (not (string= unabbreviated |
| 721 | (buffer-substring-no-properties beg end)))) |
| 722 | (last-sexp-setup-props beg end value |
| 723 | unabbreviated |
| 724 | (buffer-substring-no-properties beg end)) |
| 725 | )))) |
| 726 | |
| 727 | |
| 728 | (defvar eval-last-sexp-fake-value (make-symbol "t")) |
| 729 | |
| 730 | (defun eval-last-sexp (eval-last-sexp-arg-internal) |
| 731 | "Evaluate sexp before point; print value in minibuffer. |
| 732 | Interactively, with prefix argument, print output into current buffer. |
| 733 | Truncates long output according to the value of the variables |
| 734 | `eval-expression-print-length' and `eval-expression-print-level'. |
| 735 | |
| 736 | If `eval-expression-debug-on-error' is non-nil, which is the default, |
| 737 | this command arranges for all errors to enter the debugger." |
| 738 | (interactive "P") |
| 739 | (if (null eval-expression-debug-on-error) |
| 740 | (eval-last-sexp-1 eval-last-sexp-arg-internal) |
| 741 | (let ((value |
| 742 | (let ((debug-on-error eval-last-sexp-fake-value)) |
| 743 | (cons (eval-last-sexp-1 eval-last-sexp-arg-internal) |
| 744 | debug-on-error)))) |
| 745 | (unless (eq (cdr value) eval-last-sexp-fake-value) |
| 746 | (setq debug-on-error (cdr value))) |
| 747 | (car value)))) |
| 748 | |
| 749 | (defun eval-defun-1 (form) |
| 750 | "Treat some expressions specially. |
| 751 | Reset the `defvar' and `defcustom' variables to the initial value. |
| 752 | Reinitialize the face according to the `defface' specification." |
| 753 | ;; The code in edebug-defun should be consistent with this, but not |
| 754 | ;; the same, since this gets a macroexpended form. |
| 755 | (cond ((not (listp form)) |
| 756 | form) |
| 757 | ((and (eq (car form) 'defvar) |
| 758 | (cdr-safe (cdr-safe form)) |
| 759 | (boundp (cadr form))) |
| 760 | ;; Force variable to be re-set. |
| 761 | `(progn (defvar ,(nth 1 form) nil ,@(nthcdr 3 form)) |
| 762 | (setq-default ,(nth 1 form) ,(nth 2 form)))) |
| 763 | ;; `defcustom' is now macroexpanded to |
| 764 | ;; `custom-declare-variable' with a quoted value arg. |
| 765 | ((and (eq (car form) 'custom-declare-variable) |
| 766 | (default-boundp (eval (nth 1 form)))) |
| 767 | ;; Force variable to be bound. |
| 768 | (set-default (eval (nth 1 form)) (eval (nth 1 (nth 2 form)))) |
| 769 | form) |
| 770 | ;; `defface' is macroexpanded to `custom-declare-face'. |
| 771 | ((eq (car form) 'custom-declare-face) |
| 772 | ;; Reset the face. |
| 773 | (setq face-new-frame-defaults |
| 774 | (assq-delete-all (eval (nth 1 form)) face-new-frame-defaults)) |
| 775 | (put (eval (nth 1 form)) 'face-defface-spec nil) |
| 776 | ;; Setting `customized-face' to the new spec after calling |
| 777 | ;; the form, but preserving the old saved spec in `saved-face', |
| 778 | ;; imitates the situation when the new face spec is set |
| 779 | ;; temporarily for the current session in the customize |
| 780 | ;; buffer, thus allowing `face-user-default-spec' to use the |
| 781 | ;; new customized spec instead of the saved spec. |
| 782 | ;; Resetting `saved-face' temporarily to nil is needed to let |
| 783 | ;; `defface' change the spec, regardless of a saved spec. |
| 784 | (prog1 `(prog1 ,form |
| 785 | (put ,(nth 1 form) 'saved-face |
| 786 | ',(get (eval (nth 1 form)) 'saved-face)) |
| 787 | (put ,(nth 1 form) 'customized-face |
| 788 | ,(nth 2 form))) |
| 789 | (put (eval (nth 1 form)) 'saved-face nil))) |
| 790 | ((eq (car form) 'progn) |
| 791 | (cons 'progn (mapcar 'eval-defun-1 (cdr form)))) |
| 792 | (t form))) |
| 793 | |
| 794 | (defun eval-defun-2 () |
| 795 | "Evaluate defun that point is in or before. |
| 796 | The value is displayed in the minibuffer. |
| 797 | If the current defun is actually a call to `defvar', |
| 798 | then reset the variable using the initial value expression |
| 799 | even if the variable already has some other value. |
| 800 | \(Normally `defvar' does not change the variable's value |
| 801 | if it already has a value.\) |
| 802 | |
| 803 | With argument, insert value in current buffer after the defun. |
| 804 | Return the result of evaluation." |
| 805 | (interactive "P") |
| 806 | ;; FIXME: the print-length/level bindings should only be applied while |
| 807 | ;; printing, not while evaluating. |
| 808 | (let ((debug-on-error eval-expression-debug-on-error) |
| 809 | (print-length eval-expression-print-length) |
| 810 | (print-level eval-expression-print-level)) |
| 811 | (save-excursion |
| 812 | ;; Arrange for eval-region to "read" the (possibly) altered form. |
| 813 | ;; eval-region handles recording which file defines a function or |
| 814 | ;; variable. Re-written using `apply' to avoid capturing |
| 815 | ;; variables like `end'. |
| 816 | (apply |
| 817 | #'eval-region |
| 818 | (let ((standard-output t) |
| 819 | beg end form) |
| 820 | ;; Read the form from the buffer, and record where it ends. |
| 821 | (save-excursion |
| 822 | (end-of-defun) |
| 823 | (beginning-of-defun) |
| 824 | (setq beg (point)) |
| 825 | (setq form (read (current-buffer))) |
| 826 | (setq end (point))) |
| 827 | ;; Alter the form if necessary. |
| 828 | (setq form (eval-defun-1 (macroexpand form))) |
| 829 | (list beg end standard-output |
| 830 | `(lambda (ignore) |
| 831 | ;; Skipping to the end of the specified region |
| 832 | ;; will make eval-region return. |
| 833 | (goto-char ,end) |
| 834 | ',form)))))) |
| 835 | ;; The result of evaluation has been put onto VALUES. So return it. |
| 836 | (car values)) |
| 837 | |
| 838 | (defun eval-defun (edebug-it) |
| 839 | "Evaluate the top-level form containing point, or after point. |
| 840 | |
| 841 | If the current defun is actually a call to `defvar' or `defcustom', |
| 842 | evaluating it this way resets the variable using its initial value |
| 843 | expression even if the variable already has some other value. |
| 844 | \(Normally `defvar' and `defcustom' do not alter the value if there |
| 845 | already is one.) In an analogous way, evaluating a `defface' |
| 846 | overrides any customizations of the face, so that it becomes |
| 847 | defined exactly as the `defface' expression says. |
| 848 | |
| 849 | If `eval-expression-debug-on-error' is non-nil, which is the default, |
| 850 | this command arranges for all errors to enter the debugger. |
| 851 | |
| 852 | With a prefix argument, instrument the code for Edebug. |
| 853 | |
| 854 | If acting on a `defun' for FUNCTION, and the function was |
| 855 | instrumented, `Edebug: FUNCTION' is printed in the minibuffer. If not |
| 856 | instrumented, just FUNCTION is printed. |
| 857 | |
| 858 | If not acting on a `defun', the result of evaluation is displayed in |
| 859 | the minibuffer. This display is controlled by the variables |
| 860 | `eval-expression-print-length' and `eval-expression-print-level', |
| 861 | which see." |
| 862 | (interactive "P") |
| 863 | (cond (edebug-it |
| 864 | (require 'edebug) |
| 865 | (eval-defun (not edebug-all-defs))) |
| 866 | (t |
| 867 | (if (null eval-expression-debug-on-error) |
| 868 | (eval-defun-2) |
| 869 | (let ((old-value (make-symbol "t")) new-value value) |
| 870 | (let ((debug-on-error old-value)) |
| 871 | (setq value (eval-defun-2)) |
| 872 | (setq new-value debug-on-error)) |
| 873 | (unless (eq old-value new-value) |
| 874 | (setq debug-on-error new-value)) |
| 875 | value))))) |
| 876 | |
| 877 | ;; May still be used by some external Lisp-mode variant. |
| 878 | (define-obsolete-function-alias 'lisp-comment-indent |
| 879 | 'comment-indent-default "22.1") |
| 880 | (define-obsolete-function-alias 'lisp-mode-auto-fill 'do-auto-fill "23.1") |
| 881 | |
| 882 | (defcustom lisp-indent-offset nil |
| 883 | "If non-nil, indent second line of expressions that many more columns." |
| 884 | :group 'lisp |
| 885 | :type '(choice (const nil) integer)) |
| 886 | (put 'lisp-indent-offset 'safe-local-variable |
| 887 | (lambda (x) (or (null x) (integerp x)))) |
| 888 | |
| 889 | (defcustom lisp-indent-function 'lisp-indent-function |
| 890 | "A function to be called by `calculate-lisp-indent'. |
| 891 | It indents the arguments of a Lisp function call. This function |
| 892 | should accept two arguments: the indent-point, and the |
| 893 | `parse-partial-sexp' state at that position. One option for this |
| 894 | function is `common-lisp-indent-function'." |
| 895 | :type 'function |
| 896 | :group 'lisp) |
| 897 | |
| 898 | (defun lisp-indent-line (&optional whole-exp) |
| 899 | "Indent current line as Lisp code. |
| 900 | With argument, indent any additional lines of the same expression |
| 901 | rigidly along with this one." |
| 902 | (interactive "P") |
| 903 | (let ((indent (calculate-lisp-indent)) shift-amt end |
| 904 | (pos (- (point-max) (point))) |
| 905 | (beg (progn (beginning-of-line) (point)))) |
| 906 | (skip-chars-forward " \t") |
| 907 | (if (or (null indent) (looking-at "\\s<\\s<\\s<")) |
| 908 | ;; Don't alter indentation of a ;;; comment line |
| 909 | ;; or a line that starts in a string. |
| 910 | (goto-char (- (point-max) pos)) |
| 911 | (if (and (looking-at "\\s<") (not (looking-at "\\s<\\s<"))) |
| 912 | ;; Single-semicolon comment lines should be indented |
| 913 | ;; as comment lines, not as code. |
| 914 | (progn (indent-for-comment) (forward-char -1)) |
| 915 | (if (listp indent) (setq indent (car indent))) |
| 916 | (setq shift-amt (- indent (current-column))) |
| 917 | (if (zerop shift-amt) |
| 918 | nil |
| 919 | (delete-region beg (point)) |
| 920 | (indent-to indent))) |
| 921 | ;; If initial point was within line's indentation, |
| 922 | ;; position after the indentation. Else stay at same point in text. |
| 923 | (if (> (- (point-max) pos) (point)) |
| 924 | (goto-char (- (point-max) pos))) |
| 925 | ;; If desired, shift remaining lines of expression the same amount. |
| 926 | (and whole-exp (not (zerop shift-amt)) |
| 927 | (save-excursion |
| 928 | (goto-char beg) |
| 929 | (forward-sexp 1) |
| 930 | (setq end (point)) |
| 931 | (goto-char beg) |
| 932 | (forward-line 1) |
| 933 | (setq beg (point)) |
| 934 | (> end beg)) |
| 935 | (indent-code-rigidly beg end shift-amt))))) |
| 936 | |
| 937 | (defvar calculate-lisp-indent-last-sexp) |
| 938 | |
| 939 | (defun calculate-lisp-indent (&optional parse-start) |
| 940 | "Return appropriate indentation for current line as Lisp code. |
| 941 | In usual case returns an integer: the column to indent to. |
| 942 | If the value is nil, that means don't change the indentation |
| 943 | because the line starts inside a string. |
| 944 | |
| 945 | The value can also be a list of the form (COLUMN CONTAINING-SEXP-START). |
| 946 | This means that following lines at the same level of indentation |
| 947 | should not necessarily be indented the same as this line. |
| 948 | Then COLUMN is the column to indent to, and CONTAINING-SEXP-START |
| 949 | is the buffer position of the start of the containing expression." |
| 950 | (save-excursion |
| 951 | (beginning-of-line) |
| 952 | (let ((indent-point (point)) |
| 953 | state paren-depth |
| 954 | ;; setting this to a number inhibits calling hook |
| 955 | (desired-indent nil) |
| 956 | (retry t) |
| 957 | calculate-lisp-indent-last-sexp containing-sexp) |
| 958 | (if parse-start |
| 959 | (goto-char parse-start) |
| 960 | (beginning-of-defun)) |
| 961 | ;; Find outermost containing sexp |
| 962 | (while (< (point) indent-point) |
| 963 | (setq state (parse-partial-sexp (point) indent-point 0))) |
| 964 | ;; Find innermost containing sexp |
| 965 | (while (and retry |
| 966 | state |
| 967 | (> (setq paren-depth (elt state 0)) 0)) |
| 968 | (setq retry nil) |
| 969 | (setq calculate-lisp-indent-last-sexp (elt state 2)) |
| 970 | (setq containing-sexp (elt state 1)) |
| 971 | ;; Position following last unclosed open. |
| 972 | (goto-char (1+ containing-sexp)) |
| 973 | ;; Is there a complete sexp since then? |
| 974 | (if (and calculate-lisp-indent-last-sexp |
| 975 | (> calculate-lisp-indent-last-sexp (point))) |
| 976 | ;; Yes, but is there a containing sexp after that? |
| 977 | (let ((peek (parse-partial-sexp calculate-lisp-indent-last-sexp |
| 978 | indent-point 0))) |
| 979 | (if (setq retry (car (cdr peek))) (setq state peek))))) |
| 980 | (if retry |
| 981 | nil |
| 982 | ;; Innermost containing sexp found |
| 983 | (goto-char (1+ containing-sexp)) |
| 984 | (if (not calculate-lisp-indent-last-sexp) |
| 985 | ;; indent-point immediately follows open paren. |
| 986 | ;; Don't call hook. |
| 987 | (setq desired-indent (current-column)) |
| 988 | ;; Find the start of first element of containing sexp. |
| 989 | (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) |
| 990 | (cond ((looking-at "\\s(") |
| 991 | ;; First element of containing sexp is a list. |
| 992 | ;; Indent under that list. |
| 993 | ) |
| 994 | ((> (save-excursion (forward-line 1) (point)) |
| 995 | calculate-lisp-indent-last-sexp) |
| 996 | ;; This is the first line to start within the containing sexp. |
| 997 | ;; It's almost certainly a function call. |
| 998 | (if (= (point) calculate-lisp-indent-last-sexp) |
| 999 | ;; Containing sexp has nothing before this line |
| 1000 | ;; except the first element. Indent under that element. |
| 1001 | nil |
| 1002 | ;; Skip the first element, find start of second (the first |
| 1003 | ;; argument of the function call) and indent under. |
| 1004 | (progn (forward-sexp 1) |
| 1005 | (parse-partial-sexp (point) |
| 1006 | calculate-lisp-indent-last-sexp |
| 1007 | 0 t))) |
| 1008 | (backward-prefix-chars)) |
| 1009 | (t |
| 1010 | ;; Indent beneath first sexp on same line as |
| 1011 | ;; `calculate-lisp-indent-last-sexp'. Again, it's |
| 1012 | ;; almost certainly a function call. |
| 1013 | (goto-char calculate-lisp-indent-last-sexp) |
| 1014 | (beginning-of-line) |
| 1015 | (parse-partial-sexp (point) calculate-lisp-indent-last-sexp |
| 1016 | 0 t) |
| 1017 | (backward-prefix-chars))))) |
| 1018 | ;; Point is at the point to indent under unless we are inside a string. |
| 1019 | ;; Call indentation hook except when overridden by lisp-indent-offset |
| 1020 | ;; or if the desired indentation has already been computed. |
| 1021 | (let ((normal-indent (current-column))) |
| 1022 | (cond ((elt state 3) |
| 1023 | ;; Inside a string, don't change indentation. |
| 1024 | nil) |
| 1025 | ((and (integerp lisp-indent-offset) containing-sexp) |
| 1026 | ;; Indent by constant offset |
| 1027 | (goto-char containing-sexp) |
| 1028 | (+ (current-column) lisp-indent-offset)) |
| 1029 | ;; in this case calculate-lisp-indent-last-sexp is not nil |
| 1030 | (calculate-lisp-indent-last-sexp |
| 1031 | (or |
| 1032 | ;; try to align the parameters of a known function |
| 1033 | (and lisp-indent-function |
| 1034 | (not retry) |
| 1035 | (funcall lisp-indent-function indent-point state)) |
| 1036 | ;; If the function has no special alignment |
| 1037 | ;; or it does not apply to this argument, |
| 1038 | ;; try to align a constant-symbol under the last |
| 1039 | ;; preceding constant symbol, if there is such one of |
| 1040 | ;; the last 2 preceding symbols, in the previous |
| 1041 | ;; uncommented line. |
| 1042 | (and (save-excursion |
| 1043 | (goto-char indent-point) |
| 1044 | (skip-chars-forward " \t") |
| 1045 | (looking-at ":")) |
| 1046 | ;; The last sexp may not be at the indentation |
| 1047 | ;; where it begins, so find that one, instead. |
| 1048 | (save-excursion |
| 1049 | (goto-char calculate-lisp-indent-last-sexp) |
| 1050 | ;; Handle prefix characters and whitespace |
| 1051 | ;; following an open paren. (Bug#1012) |
| 1052 | (backward-prefix-chars) |
| 1053 | (while (and (not (looking-back "^[ \t]*\\|([ \t]+")) |
| 1054 | (or (not containing-sexp) |
| 1055 | (< (1+ containing-sexp) (point)))) |
| 1056 | (forward-sexp -1) |
| 1057 | (backward-prefix-chars)) |
| 1058 | (setq calculate-lisp-indent-last-sexp (point))) |
| 1059 | (> calculate-lisp-indent-last-sexp |
| 1060 | (save-excursion |
| 1061 | (goto-char (1+ containing-sexp)) |
| 1062 | (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) |
| 1063 | (point))) |
| 1064 | (let ((parse-sexp-ignore-comments t) |
| 1065 | indent) |
| 1066 | (goto-char calculate-lisp-indent-last-sexp) |
| 1067 | (or (and (looking-at ":") |
| 1068 | (setq indent (current-column))) |
| 1069 | (and (< (line-beginning-position) |
| 1070 | (prog2 (backward-sexp) (point))) |
| 1071 | (looking-at ":") |
| 1072 | (setq indent (current-column)))) |
| 1073 | indent)) |
| 1074 | ;; another symbols or constants not preceded by a constant |
| 1075 | ;; as defined above. |
| 1076 | normal-indent)) |
| 1077 | ;; in this case calculate-lisp-indent-last-sexp is nil |
| 1078 | (desired-indent) |
| 1079 | (t |
| 1080 | normal-indent)))))) |
| 1081 | |
| 1082 | (defun lisp-indent-function (indent-point state) |
| 1083 | "This function is the normal value of the variable `lisp-indent-function'. |
| 1084 | It is used when indenting a line within a function call, to see if the |
| 1085 | called function says anything special about how to indent the line. |
| 1086 | |
| 1087 | INDENT-POINT is the position where the user typed TAB, or equivalent. |
| 1088 | Point is located at the point to indent under (for default indentation); |
| 1089 | STATE is the `parse-partial-sexp' state for that position. |
| 1090 | |
| 1091 | If the current line is in a call to a Lisp function |
| 1092 | which has a non-nil property `lisp-indent-function', |
| 1093 | that specifies how to do the indentation. The property value can be |
| 1094 | * `defun', meaning indent `defun'-style; |
| 1095 | * an integer N, meaning indent the first N arguments specially |
| 1096 | like ordinary function arguments and then indent any further |
| 1097 | arguments like a body; |
| 1098 | * a function to call just as this function was called. |
| 1099 | If that function returns nil, that means it doesn't specify |
| 1100 | the indentation. |
| 1101 | |
| 1102 | This function also returns nil meaning don't specify the indentation." |
| 1103 | (let ((normal-indent (current-column))) |
| 1104 | (goto-char (1+ (elt state 1))) |
| 1105 | (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t) |
| 1106 | (if (and (elt state 2) |
| 1107 | (not (looking-at "\\sw\\|\\s_"))) |
| 1108 | ;; car of form doesn't seem to be a symbol |
| 1109 | (progn |
| 1110 | (if (not (> (save-excursion (forward-line 1) (point)) |
| 1111 | calculate-lisp-indent-last-sexp)) |
| 1112 | (progn (goto-char calculate-lisp-indent-last-sexp) |
| 1113 | (beginning-of-line) |
| 1114 | (parse-partial-sexp (point) |
| 1115 | calculate-lisp-indent-last-sexp 0 t))) |
| 1116 | ;; Indent under the list or under the first sexp on the same |
| 1117 | ;; line as calculate-lisp-indent-last-sexp. Note that first |
| 1118 | ;; thing on that line has to be complete sexp since we are |
| 1119 | ;; inside the innermost containing sexp. |
| 1120 | (backward-prefix-chars) |
| 1121 | (current-column)) |
| 1122 | (let ((function (buffer-substring (point) |
| 1123 | (progn (forward-sexp 1) (point)))) |
| 1124 | method) |
| 1125 | (setq method (or (get (intern-soft function) 'lisp-indent-function) |
| 1126 | (get (intern-soft function) 'lisp-indent-hook))) |
| 1127 | (cond ((or (eq method 'defun) |
| 1128 | (and (null method) |
| 1129 | (> (length function) 3) |
| 1130 | (string-match "\\`def" function))) |
| 1131 | (lisp-indent-defform state indent-point)) |
| 1132 | ((integerp method) |
| 1133 | (lisp-indent-specform method state |
| 1134 | indent-point normal-indent)) |
| 1135 | (method |
| 1136 | (funcall method indent-point state))))))) |
| 1137 | |
| 1138 | (defcustom lisp-body-indent 2 |
| 1139 | "Number of columns to indent the second line of a `(def...)' form." |
| 1140 | :group 'lisp |
| 1141 | :type 'integer) |
| 1142 | (put 'lisp-body-indent 'safe-local-variable 'integerp) |
| 1143 | |
| 1144 | (defun lisp-indent-specform (count state indent-point normal-indent) |
| 1145 | (let ((containing-form-start (elt state 1)) |
| 1146 | (i count) |
| 1147 | body-indent containing-form-column) |
| 1148 | ;; Move to the start of containing form, calculate indentation |
| 1149 | ;; to use for non-distinguished forms (> count), and move past the |
| 1150 | ;; function symbol. lisp-indent-function guarantees that there is at |
| 1151 | ;; least one word or symbol character following open paren of containing |
| 1152 | ;; form. |
| 1153 | (goto-char containing-form-start) |
| 1154 | (setq containing-form-column (current-column)) |
| 1155 | (setq body-indent (+ lisp-body-indent containing-form-column)) |
| 1156 | (forward-char 1) |
| 1157 | (forward-sexp 1) |
| 1158 | ;; Now find the start of the last form. |
| 1159 | (parse-partial-sexp (point) indent-point 1 t) |
| 1160 | (while (and (< (point) indent-point) |
| 1161 | (condition-case () |
| 1162 | (progn |
| 1163 | (setq count (1- count)) |
| 1164 | (forward-sexp 1) |
| 1165 | (parse-partial-sexp (point) indent-point 1 t)) |
| 1166 | (error nil)))) |
| 1167 | ;; Point is sitting on first character of last (or count) sexp. |
| 1168 | (if (> count 0) |
| 1169 | ;; A distinguished form. If it is the first or second form use double |
| 1170 | ;; lisp-body-indent, else normal indent. With lisp-body-indent bound |
| 1171 | ;; to 2 (the default), this just happens to work the same with if as |
| 1172 | ;; the older code, but it makes unwind-protect, condition-case, |
| 1173 | ;; with-output-to-temp-buffer, et. al. much more tasteful. The older, |
| 1174 | ;; less hacked, behavior can be obtained by replacing below with |
| 1175 | ;; (list normal-indent containing-form-start). |
| 1176 | (if (<= (- i count) 1) |
| 1177 | (list (+ containing-form-column (* 2 lisp-body-indent)) |
| 1178 | containing-form-start) |
| 1179 | (list normal-indent containing-form-start)) |
| 1180 | ;; A non-distinguished form. Use body-indent if there are no |
| 1181 | ;; distinguished forms and this is the first undistinguished form, |
| 1182 | ;; or if this is the first undistinguished form and the preceding |
| 1183 | ;; distinguished form has indentation at least as great as body-indent. |
| 1184 | (if (or (and (= i 0) (= count 0)) |
| 1185 | (and (= count 0) (<= body-indent normal-indent))) |
| 1186 | body-indent |
| 1187 | normal-indent)))) |
| 1188 | |
| 1189 | (defun lisp-indent-defform (state indent-point) |
| 1190 | (goto-char (car (cdr state))) |
| 1191 | (forward-line 1) |
| 1192 | (if (> (point) (car (cdr (cdr state)))) |
| 1193 | (progn |
| 1194 | (goto-char (car (cdr state))) |
| 1195 | (+ lisp-body-indent (current-column))))) |
| 1196 | |
| 1197 | |
| 1198 | ;; (put 'progn 'lisp-indent-function 0), say, causes progn to be indented |
| 1199 | ;; like defun if the first form is placed on the next line, otherwise |
| 1200 | ;; it is indented like any other form (i.e. forms line up under first). |
| 1201 | |
| 1202 | (put 'lambda 'lisp-indent-function 'defun) |
| 1203 | (put 'autoload 'lisp-indent-function 'defun) |
| 1204 | (put 'progn 'lisp-indent-function 0) |
| 1205 | (put 'prog1 'lisp-indent-function 1) |
| 1206 | (put 'prog2 'lisp-indent-function 2) |
| 1207 | (put 'save-excursion 'lisp-indent-function 0) |
| 1208 | (put 'save-window-excursion 'lisp-indent-function 0) |
| 1209 | (put 'save-restriction 'lisp-indent-function 0) |
| 1210 | (put 'save-match-data 'lisp-indent-function 0) |
| 1211 | (put 'save-current-buffer 'lisp-indent-function 0) |
| 1212 | (put 'let 'lisp-indent-function 1) |
| 1213 | (put 'let* 'lisp-indent-function 1) |
| 1214 | (put 'while 'lisp-indent-function 1) |
| 1215 | (put 'if 'lisp-indent-function 2) |
| 1216 | (put 'catch 'lisp-indent-function 1) |
| 1217 | (put 'condition-case 'lisp-indent-function 2) |
| 1218 | (put 'unwind-protect 'lisp-indent-function 1) |
| 1219 | (put 'with-output-to-temp-buffer 'lisp-indent-function 1) |
| 1220 | |
| 1221 | (defun indent-sexp (&optional endpos) |
| 1222 | "Indent each line of the list starting just after point. |
| 1223 | If optional arg ENDPOS is given, indent each line, stopping when |
| 1224 | ENDPOS is encountered." |
| 1225 | (interactive) |
| 1226 | (let ((indent-stack (list nil)) |
| 1227 | (next-depth 0) |
| 1228 | ;; If ENDPOS is non-nil, use nil as STARTING-POINT |
| 1229 | ;; so that calculate-lisp-indent will find the beginning of |
| 1230 | ;; the defun we are in. |
| 1231 | ;; If ENDPOS is nil, it is safe not to scan before point |
| 1232 | ;; since every line we indent is more deeply nested than point is. |
| 1233 | (starting-point (if endpos nil (point))) |
| 1234 | (last-point (point)) |
| 1235 | last-depth bol outer-loop-done inner-loop-done state this-indent) |
| 1236 | (or endpos |
| 1237 | ;; Get error now if we don't have a complete sexp after point. |
| 1238 | (save-excursion (forward-sexp 1))) |
| 1239 | (save-excursion |
| 1240 | (setq outer-loop-done nil) |
| 1241 | (while (if endpos (< (point) endpos) |
| 1242 | (not outer-loop-done)) |
| 1243 | (setq last-depth next-depth |
| 1244 | inner-loop-done nil) |
| 1245 | ;; Parse this line so we can learn the state |
| 1246 | ;; to indent the next line. |
| 1247 | ;; This inner loop goes through only once |
| 1248 | ;; unless a line ends inside a string. |
| 1249 | (while (and (not inner-loop-done) |
| 1250 | (not (setq outer-loop-done (eobp)))) |
| 1251 | (setq state (parse-partial-sexp (point) (progn (end-of-line) (point)) |
| 1252 | nil nil state)) |
| 1253 | (setq next-depth (car state)) |
| 1254 | ;; If the line contains a comment other than the sort |
| 1255 | ;; that is indented like code, |
| 1256 | ;; indent it now with indent-for-comment. |
| 1257 | ;; Comments indented like code are right already. |
| 1258 | ;; In any case clear the in-comment flag in the state |
| 1259 | ;; because parse-partial-sexp never sees the newlines. |
| 1260 | (if (car (nthcdr 4 state)) |
| 1261 | (progn (indent-for-comment) |
| 1262 | (end-of-line) |
| 1263 | (setcar (nthcdr 4 state) nil))) |
| 1264 | ;; If this line ends inside a string, |
| 1265 | ;; go straight to next line, remaining within the inner loop, |
| 1266 | ;; and turn off the \-flag. |
| 1267 | (if (car (nthcdr 3 state)) |
| 1268 | (progn |
| 1269 | (forward-line 1) |
| 1270 | (setcar (nthcdr 5 state) nil)) |
| 1271 | (setq inner-loop-done t))) |
| 1272 | (and endpos |
| 1273 | (<= next-depth 0) |
| 1274 | (progn |
| 1275 | (setq indent-stack (nconc indent-stack |
| 1276 | (make-list (- next-depth) nil)) |
| 1277 | last-depth (- last-depth next-depth) |
| 1278 | next-depth 0))) |
| 1279 | (forward-line 1) |
| 1280 | ;; Decide whether to exit. |
| 1281 | (if endpos |
| 1282 | ;; If we have already reached the specified end, |
| 1283 | ;; give up and do not reindent this line. |
| 1284 | (if (<= endpos (point)) |
| 1285 | (setq outer-loop-done t)) |
| 1286 | ;; If no specified end, we are done if we have finished one sexp. |
| 1287 | (if (<= next-depth 0) |
| 1288 | (setq outer-loop-done t))) |
| 1289 | (unless outer-loop-done |
| 1290 | (while (> last-depth next-depth) |
| 1291 | (setq indent-stack (cdr indent-stack) |
| 1292 | last-depth (1- last-depth))) |
| 1293 | (while (< last-depth next-depth) |
| 1294 | (setq indent-stack (cons nil indent-stack) |
| 1295 | last-depth (1+ last-depth))) |
| 1296 | ;; Now indent the next line according |
| 1297 | ;; to what we learned from parsing the previous one. |
| 1298 | (setq bol (point)) |
| 1299 | (skip-chars-forward " \t") |
| 1300 | ;; But not if the line is blank, or just a comment |
| 1301 | ;; (except for double-semi comments; indent them as usual). |
| 1302 | (if (or (eobp) (looking-at "\\s<\\|\n")) |
| 1303 | nil |
| 1304 | (if (and (car indent-stack) |
| 1305 | (>= (car indent-stack) 0)) |
| 1306 | (setq this-indent (car indent-stack)) |
| 1307 | (let ((val (calculate-lisp-indent |
| 1308 | (if (car indent-stack) (- (car indent-stack)) |
| 1309 | starting-point)))) |
| 1310 | (if (null val) |
| 1311 | (setq this-indent val) |
| 1312 | (if (integerp val) |
| 1313 | (setcar indent-stack |
| 1314 | (setq this-indent val)) |
| 1315 | (setcar indent-stack (- (car (cdr val)))) |
| 1316 | (setq this-indent (car val)))))) |
| 1317 | (if (and this-indent (/= (current-column) this-indent)) |
| 1318 | (progn (delete-region bol (point)) |
| 1319 | (indent-to this-indent))))) |
| 1320 | (or outer-loop-done |
| 1321 | (setq outer-loop-done (= (point) last-point)) |
| 1322 | (setq last-point (point))))))) |
| 1323 | |
| 1324 | (defun indent-pp-sexp (&optional arg) |
| 1325 | "Indent each line of the list starting just after point, or prettyprint it. |
| 1326 | A prefix argument specifies pretty-printing." |
| 1327 | (interactive "P") |
| 1328 | (if arg |
| 1329 | (save-excursion |
| 1330 | (save-restriction |
| 1331 | (narrow-to-region (point) (progn (forward-sexp 1) (point))) |
| 1332 | (pp-buffer) |
| 1333 | (goto-char (point-max)) |
| 1334 | (if (eq (char-before) ?\n) |
| 1335 | (delete-char -1))))) |
| 1336 | (indent-sexp)) |
| 1337 | |
| 1338 | ;;;; Lisp paragraph filling commands. |
| 1339 | |
| 1340 | (defcustom emacs-lisp-docstring-fill-column 65 |
| 1341 | "Value of `fill-column' to use when filling a docstring. |
| 1342 | Any non-integer value means do not use a different value of |
| 1343 | `fill-column' when filling docstrings." |
| 1344 | :type '(choice (integer) |
| 1345 | (const :tag "Use the current `fill-column'" t)) |
| 1346 | :group 'lisp) |
| 1347 | |
| 1348 | (defun lisp-fill-paragraph (&optional justify) |
| 1349 | "Like \\[fill-paragraph], but handle Emacs Lisp comments and docstrings. |
| 1350 | If any of the current line is a comment, fill the comment or the |
| 1351 | paragraph of it that point is in, preserving the comment's indentation |
| 1352 | and initial semicolons." |
| 1353 | (interactive "P") |
| 1354 | (or (fill-comment-paragraph justify) |
| 1355 | ;; Since fill-comment-paragraph returned nil, that means we're not in |
| 1356 | ;; a comment: Point is on a program line; we are interested |
| 1357 | ;; particularly in docstring lines. |
| 1358 | ;; |
| 1359 | ;; We bind `paragraph-start' and `paragraph-separate' temporarily. They |
| 1360 | ;; are buffer-local, but we avoid changing them so that they can be set |
| 1361 | ;; to make `forward-paragraph' and friends do something the user wants. |
| 1362 | ;; |
| 1363 | ;; `paragraph-start': The `(' in the character alternative and the |
| 1364 | ;; left-singlequote plus `(' sequence after the \\| alternative prevent |
| 1365 | ;; sexps and backquoted sexps that follow a docstring from being filled |
| 1366 | ;; with the docstring. This setting has the consequence of inhibiting |
| 1367 | ;; filling many program lines that are not docstrings, which is sensible, |
| 1368 | ;; because the user probably asked to fill program lines by accident, or |
| 1369 | ;; expecting indentation (perhaps we should try to do indenting in that |
| 1370 | ;; case). The `;' and `:' stop the paragraph being filled at following |
| 1371 | ;; comment lines and at keywords (e.g., in `defcustom'). Left parens are |
| 1372 | ;; escaped to keep font-locking, filling, & paren matching in the source |
| 1373 | ;; file happy. |
| 1374 | ;; |
| 1375 | ;; `paragraph-separate': A clever regexp distinguishes the first line of |
| 1376 | ;; a docstring and identifies it as a paragraph separator, so that it |
| 1377 | ;; won't be filled. (Since the first line of documentation stands alone |
| 1378 | ;; in some contexts, filling should not alter the contents the author has |
| 1379 | ;; chosen.) Only the first line of a docstring begins with whitespace |
| 1380 | ;; and a quotation mark and ends with a period or (rarely) a comma. |
| 1381 | ;; |
| 1382 | ;; The `fill-column' is temporarily bound to |
| 1383 | ;; `emacs-lisp-docstring-fill-column' if that value is an integer. |
| 1384 | (let ((paragraph-start (concat paragraph-start |
| 1385 | "\\|\\s-*\\([(;:\"]\\|`(\\|#'(\\)")) |
| 1386 | (paragraph-separate |
| 1387 | (concat paragraph-separate "\\|\\s-*\".*[,\\.]$")) |
| 1388 | (fill-column (if (and (integerp emacs-lisp-docstring-fill-column) |
| 1389 | (derived-mode-p 'emacs-lisp-mode)) |
| 1390 | emacs-lisp-docstring-fill-column |
| 1391 | fill-column))) |
| 1392 | (fill-paragraph justify)) |
| 1393 | ;; Never return nil. |
| 1394 | t)) |
| 1395 | |
| 1396 | (defun indent-code-rigidly (start end arg &optional nochange-regexp) |
| 1397 | "Indent all lines of code, starting in the region, sideways by ARG columns. |
| 1398 | Does not affect lines starting inside comments or strings, assuming that |
| 1399 | the start of the region is not inside them. |
| 1400 | |
| 1401 | Called from a program, takes args START, END, COLUMNS and NOCHANGE-REGEXP. |
| 1402 | The last is a regexp which, if matched at the beginning of a line, |
| 1403 | means don't indent that line." |
| 1404 | (interactive "r\np") |
| 1405 | (let (state) |
| 1406 | (save-excursion |
| 1407 | (goto-char end) |
| 1408 | (setq end (point-marker)) |
| 1409 | (goto-char start) |
| 1410 | (or (bolp) |
| 1411 | (setq state (parse-partial-sexp (point) |
| 1412 | (progn |
| 1413 | (forward-line 1) (point)) |
| 1414 | nil nil state))) |
| 1415 | (while (< (point) end) |
| 1416 | (or (car (nthcdr 3 state)) |
| 1417 | (and nochange-regexp |
| 1418 | (looking-at nochange-regexp)) |
| 1419 | ;; If line does not start in string, indent it |
| 1420 | (let ((indent (current-indentation))) |
| 1421 | (delete-region (point) (progn (skip-chars-forward " \t") (point))) |
| 1422 | (or (eolp) |
| 1423 | (indent-to (max 0 (+ indent arg)) 0)))) |
| 1424 | (setq state (parse-partial-sexp (point) |
| 1425 | (progn |
| 1426 | (forward-line 1) (point)) |
| 1427 | nil nil state)))))) |
| 1428 | |
| 1429 | (provide 'lisp-mode) |
| 1430 | |
| 1431 | ;;; lisp-mode.el ends here |