(debug-convert-byte-code): Convert the doc info to a string.
[bpt/emacs.git] / lisp / emacs-lisp / lisp-mode.el
CommitLineData
6594deb0
ER
1;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands.
2
3a801d0c
ER
3;; Copyright (C) 1985 Free Software Foundation, Inc.
4
e5167999 5;; Maintainer: FSF
fd7fa35a 6;; Keywords: lisp, languages
e5167999 7
a90256cc
BP
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
e5167999 12;; the Free Software Foundation; either version 2, or (at your option)
a90256cc
BP
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
e41b2db1
ER
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
a90256cc
BP
31(defvar lisp-mode-syntax-table nil "")
32(defvar emacs-lisp-mode-syntax-table nil "")
33(defvar lisp-mode-abbrev-table nil "")
34
35(if (not emacs-lisp-mode-syntax-table)
36 (let ((i 0))
37 (setq emacs-lisp-mode-syntax-table (make-syntax-table))
38 (while (< i ?0)
39 (modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
40 (setq i (1+ i)))
41 (setq i (1+ ?9))
42 (while (< i ?A)
43 (modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
44 (setq i (1+ i)))
45 (setq i (1+ ?Z))
46 (while (< i ?a)
47 (modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
48 (setq i (1+ i)))
49 (setq i (1+ ?z))
50 (while (< i 128)
51 (modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
52 (setq i (1+ i)))
53 (modify-syntax-entry ? " " emacs-lisp-mode-syntax-table)
54 (modify-syntax-entry ?\t " " emacs-lisp-mode-syntax-table)
55 (modify-syntax-entry ?\n "> " emacs-lisp-mode-syntax-table)
910762b4
RS
56 ;; Give CR the same syntax as newline, for selective-display.
57 (modify-syntax-entry ?\^m "> " emacs-lisp-mode-syntax-table)
a90256cc
BP
58 (modify-syntax-entry ?\; "< " emacs-lisp-mode-syntax-table)
59 (modify-syntax-entry ?` "' " emacs-lisp-mode-syntax-table)
60 (modify-syntax-entry ?' "' " emacs-lisp-mode-syntax-table)
61 (modify-syntax-entry ?, "' " emacs-lisp-mode-syntax-table)
62 ;; Used to be singlequote; changed for flonums.
63 (modify-syntax-entry ?. "_ " emacs-lisp-mode-syntax-table)
64 (modify-syntax-entry ?# "' " emacs-lisp-mode-syntax-table)
65 (modify-syntax-entry ?\" "\" " emacs-lisp-mode-syntax-table)
66 (modify-syntax-entry ?\\ "\\ " emacs-lisp-mode-syntax-table)
67 (modify-syntax-entry ?\( "() " emacs-lisp-mode-syntax-table)
68 (modify-syntax-entry ?\) ")( " emacs-lisp-mode-syntax-table)
69 (modify-syntax-entry ?\[ "(] " emacs-lisp-mode-syntax-table)
70 (modify-syntax-entry ?\] ")[ " emacs-lisp-mode-syntax-table)))
71
ecca85de
JB
72(if (not lisp-mode-syntax-table)
73 (progn (setq lisp-mode-syntax-table
74 (copy-syntax-table emacs-lisp-mode-syntax-table))
75 (modify-syntax-entry ?\| "\" " lisp-mode-syntax-table)
76 (modify-syntax-entry ?\[ "_ " lisp-mode-syntax-table)
77 (modify-syntax-entry ?\] "_ " lisp-mode-syntax-table)))
78
a90256cc
BP
79(define-abbrev-table 'lisp-mode-abbrev-table ())
80
81(defun lisp-mode-variables (lisp-syntax)
82 (cond (lisp-syntax
a90256cc
BP
83 (set-syntax-table lisp-mode-syntax-table)))
84 (setq local-abbrev-table lisp-mode-abbrev-table)
85 (make-local-variable 'paragraph-start)
86 (setq paragraph-start (concat "^$\\|" page-delimiter))
87 (make-local-variable 'paragraph-separate)
88 (setq paragraph-separate paragraph-start)
89 (make-local-variable 'paragraph-ignore-fill-prefix)
90 (setq paragraph-ignore-fill-prefix t)
91 (make-local-variable 'indent-line-function)
92 (setq indent-line-function 'lisp-indent-line)
93 (make-local-variable 'indent-region-function)
94 (setq indent-region-function 'lisp-indent-region)
95 (make-local-variable 'parse-sexp-ignore-comments)
96 (setq parse-sexp-ignore-comments t)
5847f861 97 (make-local-variable 'outline-regexp)
30ff174e 98 (setq outline-regexp ";;; \\|(....")
a90256cc
BP
99 (make-local-variable 'comment-start)
100 (setq comment-start ";")
101 (make-local-variable 'comment-start-skip)
c36e9c06 102 (setq comment-start-skip ";+ *")
a90256cc
BP
103 (make-local-variable 'comment-column)
104 (setq comment-column 40)
e41b2db1
ER
105 (make-local-variable 'comment-indent-function)
106 (setq comment-indent-function 'lisp-comment-indent))
a90256cc
BP
107\f
108(defvar shared-lisp-mode-map ()
109 "Keymap for commands shared by all sorts of Lisp modes.")
110
111(if shared-lisp-mode-map
112 ()
113 (setq shared-lisp-mode-map (make-sparse-keymap))
114 (define-key shared-lisp-mode-map "\e\C-q" 'indent-sexp)
6338c7ba 115 (define-key shared-lisp-mode-map "\M-q" 'lisp-fill-paragraph)
a90256cc
BP
116 (define-key shared-lisp-mode-map "\177" 'backward-delete-char-untabify)
117 (define-key shared-lisp-mode-map "\t" 'lisp-indent-line))
118
119(defvar emacs-lisp-mode-map ()
120 "Keymap for Emacs Lisp mode.
121All commands in shared-lisp-mode-map are inherited by this map.")
122
123(if emacs-lisp-mode-map
124 ()
125 (setq emacs-lisp-mode-map
126 (nconc (make-sparse-keymap) shared-lisp-mode-map))
ab67260b 127 (define-key emacs-lisp-mode-map "\e\t" 'lisp-complete-symbol)
a90256cc
BP
128 (define-key emacs-lisp-mode-map "\e\C-x" 'eval-defun))
129
130(defun emacs-lisp-mode ()
131 "Major mode for editing Lisp code to run in Emacs.
132Commands:
133Delete converts tabs to spaces as it moves back.
134Blank lines separate paragraphs. Semicolons start comments.
135\\{emacs-lisp-mode-map}
136Entry to this mode calls the value of `emacs-lisp-mode-hook'
137if that value is non-nil."
138 (interactive)
139 (kill-all-local-variables)
140 (use-local-map emacs-lisp-mode-map)
141 (set-syntax-table emacs-lisp-mode-syntax-table)
142 (setq major-mode 'emacs-lisp-mode)
143 (setq mode-name "Emacs-Lisp")
144 (lisp-mode-variables nil)
145 (run-hooks 'emacs-lisp-mode-hook))
146
147(defvar lisp-mode-map ()
148 "Keymap for ordinary Lisp mode.
149All commands in `shared-lisp-mode-map' are inherited by this map.")
150
151(if lisp-mode-map
152 ()
153 (setq lisp-mode-map
154 (nconc (make-sparse-keymap) shared-lisp-mode-map))
ef7485ce
RS
155 (define-key lisp-mode-map "\e\C-x" 'lisp-eval-defun)
156 (define-key lisp-mode-map "\C-c\C-z" 'run-lisp))
a90256cc
BP
157
158(defun lisp-mode ()
159 "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
160Commands:
161Delete converts tabs to spaces as it moves back.
162Blank lines separate paragraphs. Semicolons start comments.
163\\{lisp-mode-map}
164Note that `run-lisp' may be used either to start an inferior Lisp job
165or to switch back to an existing one.
166
167Entry to this mode calls the value of `lisp-mode-hook'
168if that value is non-nil."
169 (interactive)
170 (kill-all-local-variables)
171 (use-local-map lisp-mode-map)
172 (setq major-mode 'lisp-mode)
173 (setq mode-name "Lisp")
174 (lisp-mode-variables t)
175 (set-syntax-table lisp-mode-syntax-table)
176 (run-hooks 'lisp-mode-hook))
177
178;; This will do unless shell.el is loaded.
ef7485ce 179(defun lisp-eval-defun nil
a90256cc
BP
180 "Send the current defun to the Lisp process made by \\[run-lisp]."
181 (interactive)
182 (error "Process lisp does not exist"))
183
184(defvar lisp-interaction-mode-map ()
185 "Keymap for Lisp Interaction moe.
186All commands in `shared-lisp-mode-map' are inherited by this map.")
187
188(if lisp-interaction-mode-map
189 ()
190 (setq lisp-interaction-mode-map
191 (nconc (make-sparse-keymap) shared-lisp-mode-map))
192 (define-key lisp-interaction-mode-map "\e\C-x" 'eval-defun)
ab67260b 193 (define-key lisp-interaction-mode-map "\e\t" 'lisp-complete-symbol)
a90256cc
BP
194 (define-key lisp-interaction-mode-map "\n" 'eval-print-last-sexp))
195
196(defun lisp-interaction-mode ()
197 "Major mode for typing and evaluating Lisp forms.
198Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression
199before point, and prints its value into the buffer, advancing point.
200
201Commands:
202Delete converts tabs to spaces as it moves back.
203Paragraphs are separated only by blank lines.
204Semicolons start comments.
205\\{lisp-interaction-mode-map}
206Entry to this mode calls the value of `lisp-interaction-mode-hook'
207if that value is non-nil."
208 (interactive)
209 (kill-all-local-variables)
210 (use-local-map lisp-interaction-mode-map)
211 (setq major-mode 'lisp-interaction-mode)
212 (setq mode-name "Lisp Interaction")
213 (set-syntax-table emacs-lisp-mode-syntax-table)
214 (lisp-mode-variables nil)
215 (run-hooks 'lisp-interaction-mode-hook))
216
121f0d57 217(defun eval-print-last-sexp ()
a90256cc 218 "Evaluate sexp before point; print value into current buffer."
121f0d57 219 (interactive)
f798d950
JB
220 (let ((standard-output (current-buffer)))
221 (terpri)
222 (eval-last-sexp t)
223 (terpri)))
a90256cc 224\f
efb8f835 225(defun eval-last-sexp (eval-last-sexp-arg-internal)
a90256cc
BP
226 "Evaluate sexp before point; print value in minibuffer.
227With argument, print output into current buffer."
228 (interactive "P")
efb8f835 229 (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t))
cfe158ab 230 (opoint (point)))
19b2f8f1
RM
231 (prin1 (let ((stab (syntax-table)))
232 (eval (unwind-protect
233 (save-excursion
234 (set-syntax-table emacs-lisp-mode-syntax-table)
235 (forward-sexp -1)
cfe158ab
RS
236 (save-restriction
237 (narrow-to-region (point-min) opoint)
238 (read (current-buffer))))
19b2f8f1 239 (set-syntax-table stab)))))))
a90256cc 240
efb8f835 241(defun eval-defun (eval-defun-arg-internal)
121f0d57
RM
242 "Evaluate defun that point is in or before.
243Print value in minibuffer.
244With argument, insert value in current buffer after the defun."
a90256cc 245 (interactive "P")
efb8f835 246 (let ((standard-output (if eval-defun-arg-internal (current-buffer) t)))
19b2f8f1
RM
247 (prin1 (eval (save-excursion
248 (end-of-defun)
249 (beginning-of-defun)
250 (read (current-buffer)))))))
a90256cc
BP
251\f
252(defun lisp-comment-indent ()
253 (if (looking-at "\\s<\\s<\\s<")
254 (current-column)
255 (if (looking-at "\\s<\\s<")
256 (let ((tem (calculate-lisp-indent)))
257 (if (listp tem) (car tem) tem))
258 (skip-chars-backward " \t")
259 (max (if (bolp) 0 (1+ (current-column)))
260 comment-column))))
261
262(defconst lisp-indent-offset nil "")
263(defconst lisp-indent-function 'lisp-indent-function "")
264
265(defun lisp-indent-line (&optional whole-exp)
266 "Indent current line as Lisp code.
267With argument, indent any additional lines of the same expression
268rigidly along with this one."
269 (interactive "P")
270 (let ((indent (calculate-lisp-indent)) shift-amt beg end
271 (pos (- (point-max) (point))))
272 (beginning-of-line)
273 (setq beg (point))
274 (skip-chars-forward " \t")
275 (if (looking-at "\\s<\\s<\\s<")
276 ;; Don't alter indentation of a ;;; comment line.
328561fc 277 (goto-char (- (point-max) pos))
a90256cc
BP
278 (if (and (looking-at "\\s<") (not (looking-at "\\s<\\s<")))
279 ;; Single-semicolon comment lines should be indented
280 ;; as comment lines, not as code.
281 (progn (indent-for-comment) (forward-char -1))
282 (if (listp indent) (setq indent (car indent)))
283 (setq shift-amt (- indent (current-column)))
284 (if (zerop shift-amt)
285 nil
286 (delete-region beg (point))
287 (indent-to indent)))
288 ;; If initial point was within line's indentation,
289 ;; position after the indentation. Else stay at same point in text.
290 (if (> (- (point-max) pos) (point))
291 (goto-char (- (point-max) pos)))
292 ;; If desired, shift remaining lines of expression the same amount.
293 (and whole-exp (not (zerop shift-amt))
294 (save-excursion
295 (goto-char beg)
296 (forward-sexp 1)
297 (setq end (point))
298 (goto-char beg)
299 (forward-line 1)
300 (setq beg (point))
301 (> end beg))
302 (indent-code-rigidly beg end shift-amt)))))
303
22486a7f 304(defvar calculate-lisp-indent-last-sexp)
c0df1d61 305
a90256cc
BP
306(defun calculate-lisp-indent (&optional parse-start)
307 "Return appropriate indentation for current line as Lisp code.
308In usual case returns an integer: the column to indent to.
309Can instead return a list, whose car is the column to indent to.
310This means that following lines at the same level of indentation
311should not necessarily be indented the same way.
312The second element of the list is the buffer position
313of the start of the containing expression."
314 (save-excursion
315 (beginning-of-line)
316 (let ((indent-point (point))
317 state paren-depth
318 ;; setting this to a number inhibits calling hook
319 (desired-indent nil)
320 (retry t)
c0df1d61 321 calculate-lisp-indent-last-sexp containing-sexp)
a90256cc
BP
322 (if parse-start
323 (goto-char parse-start)
324 (beginning-of-defun))
325 ;; Find outermost containing sexp
326 (while (< (point) indent-point)
327 (setq state (parse-partial-sexp (point) indent-point 0)))
328 ;; Find innermost containing sexp
329 (while (and retry
330 state
331 (> (setq paren-depth (elt state 0)) 0))
332 (setq retry nil)
c0df1d61 333 (setq calculate-lisp-indent-last-sexp (elt state 2))
a90256cc
BP
334 (setq containing-sexp (elt state 1))
335 ;; Position following last unclosed open.
336 (goto-char (1+ containing-sexp))
337 ;; Is there a complete sexp since then?
c0df1d61
RS
338 (if (and calculate-lisp-indent-last-sexp
339 (> calculate-lisp-indent-last-sexp (point)))
a90256cc 340 ;; Yes, but is there a containing sexp after that?
c0df1d61
RS
341 (let ((peek (parse-partial-sexp calculate-lisp-indent-last-sexp
342 indent-point 0)))
a90256cc
BP
343 (if (setq retry (car (cdr peek))) (setq state peek)))))
344 (if retry
345 nil
346 ;; Innermost containing sexp found
347 (goto-char (1+ containing-sexp))
c0df1d61 348 (if (not calculate-lisp-indent-last-sexp)
a90256cc
BP
349 ;; indent-point immediately follows open paren.
350 ;; Don't call hook.
351 (setq desired-indent (current-column))
352 ;; Find the start of first element of containing sexp.
c0df1d61 353 (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
a90256cc
BP
354 (cond ((looking-at "\\s(")
355 ;; First element of containing sexp is a list.
356 ;; Indent under that list.
357 )
358 ((> (save-excursion (forward-line 1) (point))
c0df1d61 359 calculate-lisp-indent-last-sexp)
a90256cc
BP
360 ;; This is the first line to start within the containing sexp.
361 ;; It's almost certainly a function call.
c0df1d61 362 (if (= (point) calculate-lisp-indent-last-sexp)
a90256cc
BP
363 ;; Containing sexp has nothing before this line
364 ;; except the first element. Indent under that element.
365 nil
366 ;; Skip the first element, find start of second (the first
367 ;; argument of the function call) and indent under.
368 (progn (forward-sexp 1)
c0df1d61
RS
369 (parse-partial-sexp (point)
370 calculate-lisp-indent-last-sexp
371 0 t)))
a90256cc
BP
372 (backward-prefix-chars))
373 (t
c0df1d61
RS
374 ;; Indent beneath first sexp on same line as
375 ;; calculate-lisp-indent-last-sexp. Again, it's
376 ;; almost certainly a function call.
377 (goto-char calculate-lisp-indent-last-sexp)
a90256cc 378 (beginning-of-line)
c0df1d61
RS
379 (parse-partial-sexp (point) calculate-lisp-indent-last-sexp
380 0 t)
a90256cc
BP
381 (backward-prefix-chars)))))
382 ;; Point is at the point to indent under unless we are inside a string.
eb8c3be9 383 ;; Call indentation hook except when overridden by lisp-indent-offset
a90256cc
BP
384 ;; or if the desired indentation has already been computed.
385 (let ((normal-indent (current-column)))
386 (cond ((elt state 3)
387 ;; Inside a string, don't change indentation.
388 (goto-char indent-point)
389 (skip-chars-forward " \t")
390 (current-column))
391 ((and (integerp lisp-indent-offset) containing-sexp)
392 ;; Indent by constant offset
393 (goto-char containing-sexp)
394 (+ (current-column) lisp-indent-offset))
395 (desired-indent)
396 ((and (boundp 'lisp-indent-function)
397 lisp-indent-function
398 (not retry))
399 (or (funcall lisp-indent-function indent-point state)
400 normal-indent))
401 (t
f30ff39f 402 normal-indent))))))
a90256cc
BP
403
404(defun lisp-indent-function (indent-point state)
405 (let ((normal-indent (current-column)))
406 (goto-char (1+ (elt state 1)))
c0df1d61 407 (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
a90256cc
BP
408 (if (and (elt state 2)
409 (not (looking-at "\\sw\\|\\s_")))
410 ;; car of form doesn't seem to be a a symbol
411 (progn
412 (if (not (> (save-excursion (forward-line 1) (point))
c0df1d61
RS
413 calculate-lisp-indent-last-sexp))
414 (progn (goto-char calculate-lisp-indent-last-sexp)
a90256cc 415 (beginning-of-line)
c0df1d61
RS
416 (parse-partial-sexp (point)
417 calculate-lisp-indent-last-sexp 0 t)))
418 ;; Indent under the list or under the first sexp on the same
419 ;; line as calculate-lisp-indent-last-sexp. Note that first
420 ;; thing on that line has to be complete sexp since we are
421 ;; inside the innermost containing sexp.
a90256cc
BP
422 (backward-prefix-chars)
423 (current-column))
424 (let ((function (buffer-substring (point)
425 (progn (forward-sexp 1) (point))))
426 method)
2dab7802
RS
427 (setq method (or (get (intern-soft function) 'lisp-indent-function)
428 (get (intern-soft function) 'lisp-indent-hook)))
a90256cc
BP
429 (cond ((or (eq method 'defun)
430 (and (null method)
431 (> (length function) 3)
432 (string-match "\\`def" function)))
433 (lisp-indent-defform state indent-point))
434 ((integerp method)
435 (lisp-indent-specform method state
436 indent-point normal-indent))
437 (method
438 (funcall method state indent-point)))))))
439
ab69b2fb
RS
440(defconst lisp-body-indent 2
441 "Number of columns to indent the second line of a `(def...)' form.")
a90256cc
BP
442
443(defun lisp-indent-specform (count state indent-point normal-indent)
444 (let ((containing-form-start (elt state 1))
445 (i count)
446 body-indent containing-form-column)
447 ;; Move to the start of containing form, calculate indentation
448 ;; to use for non-distinguished forms (> count), and move past the
449 ;; function symbol. lisp-indent-function guarantees that there is at
450 ;; least one word or symbol character following open paren of containing
451 ;; form.
452 (goto-char containing-form-start)
453 (setq containing-form-column (current-column))
454 (setq body-indent (+ lisp-body-indent containing-form-column))
455 (forward-char 1)
456 (forward-sexp 1)
457 ;; Now find the start of the last form.
458 (parse-partial-sexp (point) indent-point 1 t)
459 (while (and (< (point) indent-point)
460 (condition-case ()
461 (progn
462 (setq count (1- count))
463 (forward-sexp 1)
464 (parse-partial-sexp (point) indent-point 1 t))
465 (error nil))))
466 ;; Point is sitting on first character of last (or count) sexp.
467 (if (> count 0)
468 ;; A distinguished form. If it is the first or second form use double
469 ;; lisp-body-indent, else normal indent. With lisp-body-indent bound
470 ;; to 2 (the default), this just happens to work the same with if as
471 ;; the older code, but it makes unwind-protect, condition-case,
472 ;; with-output-to-temp-buffer, et. al. much more tasteful. The older,
473 ;; less hacked, behavior can be obtained by replacing below with
474 ;; (list normal-indent containing-form-start).
475 (if (<= (- i count) 1)
476 (list (+ containing-form-column (* 2 lisp-body-indent))
477 containing-form-start)
478 (list normal-indent containing-form-start))
479 ;; A non-distinguished form. Use body-indent if there are no
480 ;; distinguished forms and this is the first undistinguished form,
481 ;; or if this is the first undistinguished form and the preceding
482 ;; distinguished form has indentation at least as great as body-indent.
483 (if (or (and (= i 0) (= count 0))
484 (and (= count 0) (<= body-indent normal-indent)))
485 body-indent
486 normal-indent))))
487
488(defun lisp-indent-defform (state indent-point)
489 (goto-char (car (cdr state)))
490 (forward-line 1)
491 (if (> (point) (car (cdr (cdr state))))
492 (progn
493 (goto-char (car (cdr state)))
494 (+ lisp-body-indent (current-column)))))
495
496\f
497;; (put 'progn 'lisp-indent-function 0), say, causes progn to be indented
498;; like defun if the first form is placed on the next line, otherwise
499;; it is indented like any other form (i.e. forms line up under first).
500
501(put 'lambda 'lisp-indent-function 'defun)
502(put 'autoload 'lisp-indent-function 'defun)
503(put 'progn 'lisp-indent-function 0)
504(put 'prog1 'lisp-indent-function 1)
505(put 'prog2 'lisp-indent-function 2)
506(put 'save-excursion 'lisp-indent-function 0)
507(put 'save-window-excursion 'lisp-indent-function 0)
508(put 'save-restriction 'lisp-indent-function 0)
cfe158ab 509(put 'save-match-data 'lisp-indent-function 0)
a90256cc
BP
510(put 'let 'lisp-indent-function 1)
511(put 'let* 'lisp-indent-function 1)
512(put 'while 'lisp-indent-function 1)
513(put 'if 'lisp-indent-function 2)
514(put 'catch 'lisp-indent-function 1)
515(put 'condition-case 'lisp-indent-function 2)
516(put 'unwind-protect 'lisp-indent-function 1)
517(put 'with-output-to-temp-buffer 'lisp-indent-function 1)
518
519(defun indent-sexp (&optional endpos)
520 "Indent each line of the list starting just after point.
521If optional arg ENDPOS is given, indent each line, stopping when
522ENDPOS is encountered."
523 (interactive)
daa37602
JB
524 (let ((indent-stack (list nil))
525 (next-depth 0)
526 (starting-point (point))
527 (last-point (point))
528 last-depth bol outer-loop-done inner-loop-done state this-indent)
a90256cc
BP
529 ;; Get error now if we don't have a complete sexp after point.
530 (save-excursion (forward-sexp 1))
531 (save-excursion
532 (setq outer-loop-done nil)
533 (while (if endpos (< (point) endpos)
534 (not outer-loop-done))
535 (setq last-depth next-depth
536 inner-loop-done nil)
537 ;; Parse this line so we can learn the state
538 ;; to indent the next line.
539 ;; This inner loop goes through only once
540 ;; unless a line ends inside a string.
541 (while (and (not inner-loop-done)
542 (not (setq outer-loop-done (eobp))))
543 (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
544 nil nil state))
545 (setq next-depth (car state))
546 ;; If the line contains a comment other than the sort
547 ;; that is indented like code,
548 ;; indent it now with indent-for-comment.
549 ;; Comments indented like code are right already.
550 ;; In any case clear the in-comment flag in the state
551 ;; because parse-partial-sexp never sees the newlines.
552 (if (car (nthcdr 4 state))
553 (progn (indent-for-comment)
554 (end-of-line)
555 (setcar (nthcdr 4 state) nil)))
556 ;; If this line ends inside a string,
557 ;; go straight to next line, remaining within the inner loop,
558 ;; and turn off the \-flag.
559 (if (car (nthcdr 3 state))
560 (progn
561 (forward-line 1)
562 (setcar (nthcdr 5 state) nil))
563 (setq inner-loop-done t)))
564 (and endpos
daa37602
JB
565 (<= next-depth 0)
566 (progn
567 (setq indent-stack (append indent-stack
568 (make-list (- next-depth) nil))
569 last-depth (- last-depth next-depth)
570 next-depth 0)))
a90256cc
BP
571 (or outer-loop-done
572 (setq outer-loop-done (<= next-depth 0)))
573 (if outer-loop-done
1f5038b5 574 (forward-line 1)
a90256cc
BP
575 (while (> last-depth next-depth)
576 (setq indent-stack (cdr indent-stack)
577 last-depth (1- last-depth)))
578 (while (< last-depth next-depth)
579 (setq indent-stack (cons nil indent-stack)
580 last-depth (1+ last-depth)))
581 ;; Now go to the next line and indent it according
582 ;; to what we learned from parsing the previous one.
583 (forward-line 1)
584 (setq bol (point))
585 (skip-chars-forward " \t")
586 ;; But not if the line is blank, or just a comment
587 ;; (except for double-semi comments; indent them as usual).
588 (if (or (eobp) (looking-at "\\s<\\|\n"))
589 nil
590 (if (and (car indent-stack)
591 (>= (car indent-stack) 0))
592 (setq this-indent (car indent-stack))
593 (let ((val (calculate-lisp-indent
594 (if (car indent-stack) (- (car indent-stack))
daa37602 595 starting-point))))
a90256cc
BP
596 (if (integerp val)
597 (setcar indent-stack
598 (setq this-indent val))
599 (setcar indent-stack (- (car (cdr val))))
600 (setq this-indent (car val)))))
601 (if (/= (current-column) this-indent)
602 (progn (delete-region bol (point))
603 (indent-to this-indent)))))
604 (or outer-loop-done
605 (setq outer-loop-done (= (point) last-point))
606 (setq last-point (point)))))))
607
608;; Indent every line whose first char is between START and END inclusive.
609(defun lisp-indent-region (start end)
610 (save-excursion
611 (goto-char start)
612 (and (bolp) (not (eolp))
613 (lisp-indent-line))
614 (let ((endmark (copy-marker end)))
615 (indent-sexp endmark)
616 (set-marker endmark nil))))
617\f
6338c7ba
JB
618;;;; Lisp paragraph filling commands.
619
620(defun lisp-fill-paragraph (&optional justify)
621 "Like \\[fill-paragraph], but handle Emacs Lisp comments.
622If any of the current line is a comment, fill the comment or the
623paragraph of it that point is in, preserving the comment's indentation
624and initial semicolons."
625 (interactive "P")
626 (let (
627 ;; Non-nil if the current line contains a comment.
628 has-comment
629
630 ;; If has-comment, the appropriate fill-prefix for the comment.
631 comment-fill-prefix
632 )
633
634 ;; Figure out what kind of comment we are looking at.
635 (save-excursion
636 (beginning-of-line)
637 (cond
638
639 ;; A line with nothing but a comment on it?
640 ((looking-at "[ \t]*;[; \t]*")
641 (setq has-comment t
642 comment-fill-prefix (buffer-substring (match-beginning 0)
643 (match-end 0))))
644
645 ;; A line with some code, followed by a comment? Remember that the
646 ;; semi which starts the comment shouldn't be part of a string or
647 ;; character.
648 ((progn
649 (while (not (looking-at ";\\|$"))
650 (skip-chars-forward "^;\n\"\\\\?")
651 (cond
652 ((eq (char-after (point)) ?\\) (forward-char 2))
653 ((memq (char-after (point)) '(?\" ??)) (forward-sexp 1))))
654 (looking-at ";+[\t ]*"))
655 (setq has-comment t)
656 (setq comment-fill-prefix
657 (concat (make-string (current-column) ? )
658 (buffer-substring (match-beginning 0) (match-end 0)))))))
659
660 (if (not has-comment)
661 (fill-paragraph justify)
662
663 ;; Narrow to include only the comment, and then fill the region.
664 (save-restriction
665 (narrow-to-region
666 ;; Find the first line we should include in the region to fill.
667 (save-excursion
668 (while (and (zerop (forward-line -1))
669 (looking-at "^[ \t]*;")))
670 ;; We may have gone to far. Go forward again.
671 (or (looking-at "^[ \t]*;")
672 (forward-line 1))
673 (point))
674 ;; Find the beginning of the first line past the region to fill.
675 (save-excursion
676 (while (progn (forward-line 1)
677 (looking-at "^[ \t]*;")))
678 (point)))
679
680 ;; Lines with only semicolons on them can be paragraph boundaries.
681 (let ((paragraph-start (concat paragraph-start "\\|^[ \t;]*$"))
682 (paragraph-separate (concat paragraph-start "\\|^[ \t;]*$"))
683 (fill-prefix comment-fill-prefix))
684 (fill-paragraph justify))))))
685
686\f
a90256cc
BP
687(defun indent-code-rigidly (start end arg &optional nochange-regexp)
688 "Indent all lines of code, starting in the region, sideways by ARG columns.
689Does not affect lines starting inside comments or strings, assuming that
690the start of the region is not inside them.
691
692Called from a program, takes args START, END, COLUMNS and NOCHANGE-REGEXP.
693The last is a regexp which, if matched at the beginning of a line,
694means don't indent that line."
695 (interactive "r\np")
696 (let (state)
697 (save-excursion
698 (goto-char end)
699 (setq end (point-marker))
700 (goto-char start)
701 (or (bolp)
702 (setq state (parse-partial-sexp (point)
703 (progn
704 (forward-line 1) (point))
705 nil nil state)))
706 (while (< (point) end)
707 (or (car (nthcdr 3 state))
708 (and nochange-regexp
709 (looking-at nochange-regexp))
710 ;; If line does not start in string, indent it
711 (let ((indent (current-indentation)))
712 (delete-region (point) (progn (skip-chars-forward " \t") (point)))
713 (or (eolp)
714 (indent-to (max 0 (+ indent arg)) 0))))
715 (setq state (parse-partial-sexp (point)
716 (progn
717 (forward-line 1) (point))
718 nil nil state))))))
49116ac0
JB
719
720(provide 'lisp-mode)
721
6594deb0 722;;; lisp-mode.el ends here