cl-indent.el 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. ;;; cl-indent.el --- Enhanced lisp-indent mode -*- lexical-binding:t -*-
  2. ;; Copyright (C) 1987, 2000-2017 Free Software Foundation, Inc.
  3. ;; Author: Richard Mlynarik <mly@eddie.mit.edu>
  4. ;; Created: July 1987
  5. ;; Maintainer: emacs-devel@gnu.org
  6. ;; Keywords: lisp, tools
  7. ;; Package: emacs
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;; This package supplies a single entry point, common-lisp-indent-function,
  21. ;; which performs indentation in the preferred style for Common Lisp code.
  22. ;; It is also a suitable function for indenting Emacs lisp code.
  23. ;;
  24. ;; To enable it:
  25. ;;
  26. ;; (setq lisp-indent-function 'common-lisp-indent-function)
  27. ;;; Code:
  28. (eval-when-compile (require 'cl-lib))
  29. (defgroup lisp-indent nil
  30. "Indentation in Lisp."
  31. :group 'lisp)
  32. (defcustom lisp-indent-maximum-backtracking 3
  33. "Maximum depth to backtrack out from a sublist for structured indentation.
  34. If this variable is 0, no backtracking will occur and forms such as `flet'
  35. may not be correctly indented."
  36. :type 'integer
  37. :group 'lisp-indent)
  38. (defcustom lisp-tag-indentation 1
  39. "Indentation of tags relative to containing list.
  40. This variable is used by the function `lisp-indent-tagbody'."
  41. :type 'integer
  42. :group 'lisp-indent)
  43. (defcustom lisp-tag-body-indentation 3
  44. "Indentation of non-tagged lines relative to containing list.
  45. This variable is used by the function `lisp-indent-tagbody' to indent normal
  46. lines (lines without tags).
  47. The indentation is relative to the indentation of the parenthesis enclosing
  48. the special form. If the value is t, the body of tags will be indented
  49. as a block at the same indentation as the first s-expression following
  50. the tag. In this case, any forms before the first tag are indented
  51. by `lisp-body-indent'."
  52. :type 'integer
  53. :group 'lisp-indent)
  54. (defcustom lisp-backquote-indentation t
  55. "Whether or not to indent backquoted lists as code.
  56. If nil, indent backquoted lists as data, i.e., like quoted lists."
  57. :type 'boolean
  58. :group 'lisp-indent)
  59. (defcustom lisp-loop-keyword-indentation 3
  60. "Indentation of loop keywords in extended loop forms."
  61. :type 'integer
  62. :group 'lisp-indent)
  63. (defcustom lisp-loop-forms-indentation 5
  64. "Indentation of forms in extended loop forms."
  65. :type 'integer
  66. :group 'lisp-indent)
  67. (defcustom lisp-simple-loop-indentation 3
  68. "Indentation of forms in simple loop forms."
  69. :type 'integer
  70. :group 'lisp-indent)
  71. (defcustom lisp-lambda-list-keyword-alignment nil
  72. "Whether to vertically align lambda-list keywords together.
  73. If nil (the default), keyworded lambda-list parts are aligned
  74. with the initial mandatory arguments, like this:
  75. \(defun foo (arg1 arg2 &rest rest
  76. &key key1 key2)
  77. #|...|#)
  78. If non-nil, alignment is done with the first keyword
  79. \(or falls back to the previous case), as in:
  80. \(defun foo (arg1 arg2 &rest rest
  81. &key key1 key2)
  82. #|...|#)"
  83. :version "24.1"
  84. :type 'boolean
  85. :group 'lisp-indent)
  86. (defcustom lisp-lambda-list-keyword-parameter-indentation 2
  87. "Indentation of lambda list keyword parameters.
  88. See `lisp-lambda-list-keyword-parameter-alignment'
  89. for more information."
  90. :version "24.1"
  91. :type 'integer
  92. :group 'lisp-indent)
  93. (defcustom lisp-lambda-list-keyword-parameter-alignment nil
  94. "Whether to vertically align lambda-list keyword parameters together.
  95. If nil (the default), the parameters are aligned
  96. with their corresponding keyword, plus the value of
  97. `lisp-lambda-list-keyword-parameter-indentation', like this:
  98. \(defun foo (arg1 arg2 &key key1 key2
  99. key3 key4)
  100. #|...|#)
  101. If non-nil, alignment is done with the first parameter
  102. \(or falls back to the previous case), as in:
  103. \(defun foo (arg1 arg2 &key key1 key2
  104. key3 key4)
  105. #|...|#)"
  106. :version "24.1"
  107. :type 'boolean
  108. :group 'lisp-indent)
  109. (defcustom lisp-indent-backquote-substitution-mode t
  110. "How to indent substitutions in backquotes.
  111. If t, the default, indent substituted forms normally.
  112. If nil, do not apply special indentation rule to substituted
  113. forms. If `corrected', subtract the `,' or `,@' from the form
  114. column, indenting as if this character sequence were not present.
  115. In any case, do not backtrack beyond a backquote substitution.
  116. Until Emacs 25.1, the nil behavior was hard-wired."
  117. :version "25.1"
  118. :type '(choice (const corrected) (const nil) (const t))
  119. :group 'lisp-indent)
  120. (defvar lisp-indent-defun-method '(4 &lambda &body)
  121. "Defun-like indentation method.
  122. This applies when the value of the `common-lisp-indent-function' property
  123. is set to `defun'.")
  124. (defun lisp-extended-loop-p (loop-start)
  125. "True if an extended loop form starts at LOOP-START."
  126. (condition-case ()
  127. (save-excursion
  128. (goto-char loop-start)
  129. (forward-char 1)
  130. (forward-sexp 2)
  131. (backward-sexp 1)
  132. (looking-at "\\(:\\|\\sw\\)"))
  133. (error t)))
  134. (defun lisp-indent-find-method (symbol &optional no-compat)
  135. "Find the lisp indentation function for SYMBOL.
  136. If NO-COMPAT is non-nil, do not retrieve indenters intended for
  137. the standard lisp indent package."
  138. (or (and (derived-mode-p 'emacs-lisp-mode)
  139. (get symbol 'common-lisp-indent-function-for-elisp))
  140. (get symbol 'common-lisp-indent-function)
  141. (and (not no-compat)
  142. (get symbol 'lisp-indent-function))))
  143. (defun common-lisp-loop-part-indentation (indent-point state)
  144. "Compute the indentation of loop form constituents."
  145. (let* ((loop-indentation (save-excursion
  146. (goto-char (elt state 1))
  147. (current-column))))
  148. (when (and (eq lisp-indent-backquote-substitution-mode 'corrected))
  149. (save-excursion
  150. (goto-char (elt state 1))
  151. (cl-incf loop-indentation
  152. (cond ((eq (char-before) ?,) -1)
  153. ((and (eq (char-before) ?@)
  154. (progn (backward-char)
  155. (eq (char-before) ?,)))
  156. -2)
  157. (t 0)))))
  158. (goto-char indent-point)
  159. (beginning-of-line)
  160. (list
  161. (cond ((not (lisp-extended-loop-p (elt state 1)))
  162. (+ loop-indentation lisp-simple-loop-indentation))
  163. ((looking-at "^\\s-*\\(:?\\sw+\\|;\\)")
  164. (+ loop-indentation lisp-loop-keyword-indentation))
  165. (t
  166. (+ loop-indentation lisp-loop-forms-indentation)))
  167. ;; Tell the caller that the next line needs recomputation, even
  168. ;; though it doesn't start a sexp.
  169. loop-indentation)))
  170. ;; Cf (info "(elisp)Specification List")
  171. ;;;###autoload
  172. (defun common-lisp-indent-function (indent-point state)
  173. "Function to indent the arguments of a Lisp function call.
  174. This is suitable for use as the value of the variable
  175. `lisp-indent-function'. INDENT-POINT is the point at which the
  176. indentation function is called, and STATE is the
  177. `parse-partial-sexp' state at that position. Browse the
  178. `lisp-indent' customize group for options affecting the behavior
  179. of this function.
  180. If the indentation point is in a call to a Lisp function, that
  181. function's `common-lisp-indent-function' property specifies how
  182. this function should indent it. Possible values for this
  183. property are:
  184. * defun, meaning indent according to `lisp-indent-defun-method';
  185. i.e., like (4 &lambda &body), as explained below.
  186. * any other symbol, meaning a function to call. The function should
  187. take the arguments: PATH STATE INDENT-POINT SEXP-COLUMN NORMAL-INDENT.
  188. PATH is a list of integers describing the position of point in terms of
  189. list-structure with respect to the containing lists. For example, in
  190. ((a b c (d foo) f) g), foo has a path of (0 3 1). In other words,
  191. to reach foo take the 0th element of the outermost list, then
  192. the 3rd element of the next list, and finally the 1st element.
  193. STATE and INDENT-POINT are as in the arguments to
  194. `common-lisp-indent-function'. SEXP-COLUMN is the column of
  195. the open parenthesis of the innermost containing list.
  196. NORMAL-INDENT is the column the indentation point was
  197. originally in. This function should behave like `lisp-indent-259'.
  198. * an integer N, meaning indent the first N arguments like
  199. function arguments, and any further arguments like a body.
  200. This is equivalent to (4 4 ... &body).
  201. * a list. The list element in position M specifies how to indent the Mth
  202. function argument. If there are fewer elements than function arguments,
  203. the last list element applies to all remaining arguments. The accepted
  204. list elements are:
  205. * nil, meaning the default indentation.
  206. * an integer, specifying an explicit indentation.
  207. * &lambda. Indent the argument (which may be a list) by 4.
  208. * &rest. When used, this must be the penultimate element. The
  209. element after this one applies to all remaining arguments.
  210. * &body. This is equivalent to &rest lisp-body-indent, i.e., indent
  211. all remaining elements by `lisp-body-indent'.
  212. * &whole. This must be followed by nil, an integer, or a
  213. function symbol. This indentation is applied to the
  214. associated argument, and as a base indent for all remaining
  215. arguments. For example, an integer P means indent this
  216. argument by P, and all remaining arguments by P, plus the
  217. value specified by their associated list element.
  218. * a symbol. A function to call, with the 6 arguments specified above.
  219. * a list, with elements as described above. This applies when the
  220. associated function argument is itself a list. Each element of the list
  221. specifies how to indent the associated argument.
  222. For example, the function `case' has an indent property
  223. \(4 &rest (&whole 2 &rest 1)), meaning:
  224. * indent the first argument by 4.
  225. * arguments after the first should be lists, and there may be any number
  226. of them. The first list element has an offset of 2, all the rest
  227. have an offset of 2+1=3.
  228. If the current mode is actually `emacs-lisp-mode', look for a
  229. `common-lisp-indent-function-for-elisp' property before looking
  230. at `common-lisp-indent-function' and, if set, use its value
  231. instead."
  232. ;; FIXME: why do we need to special-case loop?
  233. (if (save-excursion (goto-char (elt state 1))
  234. (and (looking-at (if (derived-mode-p 'emacs-lisp-mode)
  235. "(\\(cl-\\)?loop"
  236. "([Ll][Oo][Oo][Pp]"))
  237. (or lisp-indent-backquote-substitution-mode
  238. (not
  239. (or (and (eq (char-before) ?@)
  240. (progn (backward-char)
  241. (eq (char-before) ?,)))
  242. (eq (char-before) ?,))))))
  243. (common-lisp-loop-part-indentation indent-point state)
  244. (common-lisp-indent-function-1 indent-point state)))
  245. (defun common-lisp-indent-function-1 (indent-point state)
  246. (let ((normal-indent (current-column)))
  247. ;; Walk up list levels until we see something
  248. ;; which does special things with subforms.
  249. (let ((depth 0)
  250. ;; Path describes the position of point in terms of
  251. ;; list-structure with respect to containing lists.
  252. ;; `foo' has a path of (0 3 1) in `((a b c (d foo) f) g)'.
  253. (path ())
  254. ;; set non-nil when somebody works out the indentation to use
  255. calculated
  256. ;; If non-nil, this is an indentation to use
  257. ;; if nothing else specifies it more firmly.
  258. tentative-calculated
  259. ;; the position of the open-paren of the innermost containing list
  260. (containing-form-start (elt state 1))
  261. ;; the column of the above
  262. sexp-column)
  263. ;; Move to start of innermost containing list
  264. (goto-char containing-form-start)
  265. (setq sexp-column (current-column))
  266. ;; Look over successively less-deep containing forms
  267. (while (and (not calculated)
  268. (< depth lisp-indent-maximum-backtracking))
  269. (let ((containing-sexp (point)))
  270. (forward-char 1)
  271. (parse-partial-sexp (point) indent-point 1 t)
  272. ;; Move to the car of the relevant containing form
  273. (let (tem function method tentative-defun)
  274. (if (not (looking-at "\\sw\\|\\s_"))
  275. ;; This form doesn't seem to start with a symbol
  276. (setq function nil method nil)
  277. (setq tem (point))
  278. (forward-sexp 1)
  279. (setq function (downcase (buffer-substring-no-properties
  280. tem (point))))
  281. (goto-char tem)
  282. ;; Elisp generally provides CL functionality with a CL
  283. ;; prefix, so if we have a special indenter for the
  284. ;; unprefixed version, prefer it over whatever's defined
  285. ;; for the cl- version. Users can override this
  286. ;; heuristic by defining a
  287. ;; common-lisp-indent-function-for-elisp property on the
  288. ;; cl- version.
  289. (when (and (derived-mode-p 'emacs-lisp-mode)
  290. (not (lisp-indent-find-method
  291. (intern-soft function) t))
  292. (string-match "\\`cl-" function)
  293. (setf tem (intern-soft
  294. (substring function (match-end 0))))
  295. (lisp-indent-find-method tem t))
  296. (setf function (symbol-name tem)))
  297. (setq tem (intern-soft function)
  298. method (lisp-indent-find-method tem))
  299. ;; The pleblisp package feature
  300. (when (and (null tem)
  301. (string-match ":[^:]+" function))
  302. (setq function (substring function (1+ (match-beginning 0)))
  303. tem (intern-soft function)
  304. method (lisp-indent-find-method tem))))
  305. (let ((n 0))
  306. ;; How far into the containing form is the current form?
  307. (if (< (point) indent-point)
  308. (while (condition-case ()
  309. (progn
  310. (forward-sexp 1)
  311. (if (>= (point) indent-point)
  312. nil
  313. (parse-partial-sexp (point)
  314. indent-point 1 t)
  315. (setq n (1+ n))
  316. t))
  317. (error nil))))
  318. (setq path (cons n path)))
  319. ;; backwards compatibility.
  320. (cond ((null function))
  321. ((null method)
  322. (when (null (cdr path))
  323. ;; (package prefix was stripped off above)
  324. (cond ((string-match "\\`def"
  325. function)
  326. (setq tentative-defun t))
  327. ((string-match
  328. (eval-when-compile
  329. (concat "\\`\\("
  330. (regexp-opt '("with" "without" "do"))
  331. "\\)-"))
  332. function)
  333. (setq method '(&lambda &body))))))
  334. ;; backwards compatibility. Bletch.
  335. ((eq method 'defun)
  336. (setq method lisp-indent-defun-method)))
  337. (cond ((and (or (eq (char-after (1- containing-sexp)) ?\')
  338. (and (not lisp-backquote-indentation)
  339. (eq (char-after (1- containing-sexp)) ?\`)))
  340. (not (eq (char-after (- containing-sexp 2)) ?\#)))
  341. ;; No indentation for "'(...)" elements
  342. (setq calculated (1+ sexp-column)))
  343. ((when
  344. (or (eq (char-after (1- containing-sexp)) ?\,)
  345. (and (eq (char-after (1- containing-sexp)) ?\@)
  346. (eq (char-after (- containing-sexp 2)) ?\,)))
  347. ;; ",(...)" or ",@(...)"
  348. (when (eq lisp-indent-backquote-substitution-mode
  349. 'corrected)
  350. (cl-incf sexp-column -1)
  351. (when (eq (char-after (1- containing-sexp)) ?\@)
  352. (cl-incf sexp-column -1)))
  353. (cond (lisp-indent-backquote-substitution-mode
  354. (setf tentative-calculated normal-indent)
  355. (setq depth lisp-indent-maximum-backtracking)
  356. nil)
  357. (t (setq calculated normal-indent)))))
  358. ((eq (char-after (1- containing-sexp)) ?\#)
  359. ;; "#(...)"
  360. (setq calculated (1+ sexp-column)))
  361. ((null method)
  362. ;; If this looks like a call to a `def...' form,
  363. ;; think about indenting it as one, but do it
  364. ;; tentatively for cases like
  365. ;; (flet ((defunp ()
  366. ;; nil)))
  367. ;; Set both normal-indent and tentative-calculated.
  368. ;; The latter ensures this value gets used
  369. ;; if there are no relevant containing constructs.
  370. ;; The former ensures this value gets used
  371. ;; if there is a relevant containing construct
  372. ;; but we are nested within the structure levels
  373. ;; that it specifies indentation for.
  374. (if tentative-defun
  375. (setq tentative-calculated
  376. (common-lisp-indent-call-method
  377. function lisp-indent-defun-method
  378. path state indent-point
  379. sexp-column normal-indent)
  380. normal-indent tentative-calculated)))
  381. ((integerp method)
  382. ;; convenient top-level hack.
  383. ;; (also compatible with lisp-indent-function)
  384. ;; The number specifies how many `distinguished'
  385. ;; forms there are before the body starts
  386. ;; Equivalent to (4 4 ... &body)
  387. (setq calculated (cond ((cdr path)
  388. normal-indent)
  389. ((<= (car path) method)
  390. ;; `distinguished' form
  391. (list (+ sexp-column 4)
  392. containing-form-start))
  393. ((= (car path) (1+ method))
  394. ;; first body form.
  395. (+ sexp-column lisp-body-indent))
  396. (t
  397. ;; other body form
  398. normal-indent))))
  399. (t
  400. (setq calculated
  401. (common-lisp-indent-call-method
  402. function method path state indent-point
  403. sexp-column normal-indent)))))
  404. (goto-char containing-sexp)
  405. (unless calculated
  406. (condition-case ()
  407. (progn (backward-up-list 1)
  408. (setq depth (1+ depth)))
  409. (error (setq depth lisp-indent-maximum-backtracking))))))
  410. (or calculated tentative-calculated))))
  411. ;; Dynamically bound in common-lisp-indent-call-method.
  412. (defvar lisp-indent-error-function)
  413. (defun common-lisp-indent-call-method (function method path state indent-point
  414. sexp-column normal-indent)
  415. (let ((lisp-indent-error-function function))
  416. (if (symbolp method)
  417. (funcall method
  418. path state indent-point
  419. sexp-column normal-indent)
  420. (lisp-indent-259 method path state indent-point
  421. sexp-column normal-indent))))
  422. (defun lisp-indent-report-bad-format (m)
  423. (error "%s has a badly-formed %s property: %s"
  424. ;; Love those free variable references!!
  425. lisp-indent-error-function 'common-lisp-indent-function m))
  426. ;; Lambda-list indentation is now done in LISP-INDENT-LAMBDA-LIST.
  427. ;; See also `lisp-lambda-list-keyword-alignment',
  428. ;; `lisp-lambda-list-keyword-parameter-alignment' and
  429. ;; `lisp-lambda-list-keyword-parameter-indentation' -- dvl
  430. (defvar lisp-indent-lambda-list-keywords-regexp
  431. "&\\(\
  432. optional\\|rest\\|key\\|allow-other-keys\\|aux\\|whole\\|body\\|environment\
  433. \\)\\([ \t]\\|$\\)"
  434. "Regular expression matching lambda-list keywords.")
  435. (defun lisp-indent-lambda-list
  436. (indent-point sexp-column containing-form-start)
  437. (let (limit)
  438. (cond ((save-excursion
  439. (goto-char indent-point)
  440. (beginning-of-line)
  441. (skip-chars-forward " \t")
  442. (setq limit (point))
  443. (looking-at lisp-indent-lambda-list-keywords-regexp))
  444. ;; We're facing a lambda-list keyword.
  445. (if lisp-lambda-list-keyword-alignment
  446. ;; Align to the first keyword if any, or to the beginning of
  447. ;; the lambda-list.
  448. (save-excursion
  449. (goto-char containing-form-start)
  450. (save-match-data
  451. (if (re-search-forward
  452. lisp-indent-lambda-list-keywords-regexp
  453. limit t)
  454. (progn
  455. (goto-char (match-beginning 0))
  456. (current-column))
  457. (1+ sexp-column))))
  458. ;; Align to the beginning of the lambda-list.
  459. (1+ sexp-column)))
  460. (t
  461. ;; Otherwise, align to the first argument of the last lambda-list
  462. ;; keyword, the keyword itself, or the beginning of the
  463. ;; lambda-list.
  464. (save-excursion
  465. (goto-char indent-point)
  466. (forward-line -1)
  467. (end-of-line)
  468. (save-match-data
  469. (if (re-search-backward lisp-indent-lambda-list-keywords-regexp
  470. containing-form-start t)
  471. (let* ((keyword-posn
  472. (progn
  473. (goto-char (match-beginning 0))
  474. (current-column)))
  475. (indented-keyword-posn
  476. (+ keyword-posn
  477. lisp-lambda-list-keyword-parameter-indentation)))
  478. (goto-char (match-end 0))
  479. (skip-chars-forward " \t")
  480. (if (eolp)
  481. indented-keyword-posn
  482. (if lisp-lambda-list-keyword-parameter-alignment
  483. (current-column)
  484. indented-keyword-posn)))
  485. (1+ sexp-column))))))))
  486. ;; Blame the crufty control structure on dynamic scoping
  487. ;; -- not on me!
  488. (defun lisp-indent-259
  489. (method path state indent-point sexp-column normal-indent)
  490. (catch 'exit
  491. (let ((p path)
  492. (containing-form-start (elt state 1))
  493. n tem tail)
  494. ;; Isn't tail-recursion wonderful?
  495. (while p
  496. ;; This while loop is for destructuring.
  497. ;; p is set to (cdr p) each iteration.
  498. (if (not (consp method)) (lisp-indent-report-bad-format method))
  499. (setq n (1- (car p))
  500. p (cdr p)
  501. tail nil)
  502. (while n
  503. ;; This while loop is for advancing along a method
  504. ;; until the relevant (possibly &rest/&body) pattern
  505. ;; is reached.
  506. ;; n is set to (1- n) and method to (cdr method)
  507. ;; each iteration.
  508. (setq tem (car method))
  509. (or (eq tem 'nil) ;default indentation
  510. (eq tem '&lambda) ;lambda list
  511. (and (eq tem '&body) (null (cdr method)))
  512. (and (eq tem '&rest)
  513. (consp (cdr method))
  514. (null (cddr method)))
  515. (integerp tem) ;explicit indentation specified
  516. (and (consp tem) ;destructuring
  517. (eq (car tem) '&whole)
  518. (or (symbolp (cadr tem))
  519. (integerp (cadr tem))))
  520. (and (symbolp tem) ;a function to call to do the work.
  521. (null (cdr method)))
  522. (lisp-indent-report-bad-format method))
  523. (cond ((and tail (not (consp tem)))
  524. ;; indent tail of &rest in same way as first elt of rest
  525. (throw 'exit normal-indent))
  526. ((eq tem '&body)
  527. ;; &body means (&rest <lisp-body-indent>)
  528. (throw 'exit
  529. (if (and (= n 0) ;first body form
  530. (null p)) ;not in subforms
  531. (+ sexp-column
  532. lisp-body-indent)
  533. normal-indent)))
  534. ((eq tem '&rest)
  535. ;; this pattern holds for all remaining forms
  536. (setq tail (> n 0)
  537. n 0
  538. method (cdr method)))
  539. ((> n 0)
  540. ;; try next element of pattern
  541. (setq n (1- n)
  542. method (cdr method))
  543. (if (< n 0)
  544. ;; Too few elements in pattern.
  545. (throw 'exit normal-indent)))
  546. ((eq tem 'nil)
  547. (throw 'exit (if (consp normal-indent)
  548. normal-indent
  549. (list normal-indent containing-form-start))))
  550. ((eq tem '&lambda)
  551. (throw 'exit
  552. (cond ((null p)
  553. (list (+ sexp-column 4) containing-form-start))
  554. ((null (cdr p))
  555. ;; Indentation within a lambda-list. -- dvl
  556. (list (lisp-indent-lambda-list
  557. indent-point
  558. sexp-column
  559. containing-form-start)
  560. containing-form-start))
  561. (t
  562. normal-indent))))
  563. ((integerp tem)
  564. (throw 'exit
  565. (if (null p) ;not in subforms
  566. (list (+ sexp-column tem) containing-form-start)
  567. normal-indent)))
  568. ((symbolp tem) ;a function to call
  569. (throw 'exit
  570. (funcall tem path state indent-point
  571. sexp-column normal-indent)))
  572. (t
  573. ;; must be a destructing frob
  574. (if (not (null p))
  575. ;; descend
  576. (setq method (cddr tem)
  577. n nil)
  578. (setq tem (cadr tem))
  579. (throw 'exit
  580. (cond (tail
  581. normal-indent)
  582. ((eq tem 'nil)
  583. (list normal-indent
  584. containing-form-start))
  585. ((integerp tem)
  586. (list (+ sexp-column tem)
  587. containing-form-start))
  588. (t
  589. (funcall tem path state indent-point
  590. sexp-column normal-indent))))))))))))
  591. (defun lisp-indent-tagbody (path state indent-point sexp-column normal-indent)
  592. (if (not (null (cdr path)))
  593. normal-indent
  594. (save-excursion
  595. (goto-char indent-point)
  596. (beginning-of-line)
  597. (skip-chars-forward " \t")
  598. (list (cond ((looking-at "\\sw\\|\\s_")
  599. ;; a tagbody tag
  600. (+ sexp-column lisp-tag-indentation))
  601. ((integerp lisp-tag-body-indentation)
  602. (+ sexp-column lisp-tag-body-indentation))
  603. ((eq lisp-tag-body-indentation 't)
  604. (condition-case ()
  605. (progn (backward-sexp 1) (current-column))
  606. (error (1+ sexp-column))))
  607. (t (+ sexp-column lisp-body-indent)))
  608. ; (cond ((integerp lisp-tag-body-indentation)
  609. ; (+ sexp-column lisp-tag-body-indentation))
  610. ; ((eq lisp-tag-body-indentation 't)
  611. ; normal-indent)
  612. ; (t
  613. ; (+ sexp-column lisp-body-indent)))
  614. (elt state 1)
  615. ))))
  616. (defun lisp-indent-do (path state indent-point sexp-column normal-indent)
  617. (if (>= (car path) 3)
  618. (let ((lisp-tag-body-indentation lisp-body-indent))
  619. (funcall (function lisp-indent-tagbody)
  620. path state indent-point sexp-column normal-indent))
  621. (funcall (function lisp-indent-259)
  622. '((&whole nil &rest
  623. ;; the following causes weird indentation
  624. ;;(&whole 1 1 2 nil)
  625. )
  626. (&whole nil &rest 1))
  627. path state indent-point sexp-column normal-indent)))
  628. ;; LISP-INDENT-DEFMETHOD now supports the presence of more than one method
  629. ;; qualifier and indents the method's lambda list properly. -- dvl
  630. (defun lisp-indent-defmethod
  631. (path state indent-point sexp-column normal-indent)
  632. (lisp-indent-259
  633. (let ((nqual 0))
  634. (if (and (>= (car path) 3)
  635. (save-excursion
  636. (beginning-of-defun)
  637. (forward-char 1)
  638. (forward-sexp 2)
  639. (skip-chars-forward " \t\n")
  640. (while (looking-at "\\sw\\|\\s_")
  641. (cl-incf nqual)
  642. (forward-sexp)
  643. (skip-chars-forward " \t\n"))
  644. (> nqual 0)))
  645. (append '(4) (make-list nqual 4) '(&lambda &body))
  646. (get 'defun 'common-lisp-indent-function)))
  647. path state indent-point sexp-column normal-indent))
  648. (defun lisp-indent-function-lambda-hack (path _state _indent-point
  649. sexp-column normal-indent)
  650. ;; indent (function (lambda () <newline> <body-forms>)) kludgily.
  651. (if (or (cdr path) ; wtf?
  652. (> (car path) 3))
  653. ;; line up under previous body form
  654. normal-indent
  655. ;; line up under function rather than under lambda in order to
  656. ;; conserve horizontal space. (Which is what #' is for.)
  657. (condition-case ()
  658. (save-excursion
  659. (backward-up-list 2)
  660. (forward-char 1)
  661. (if (looking-at "\\(lisp:+\\)?function\\(\\Sw\\|\\S_\\)")
  662. (+ lisp-body-indent -1 (current-column))
  663. (+ sexp-column lisp-body-indent)))
  664. (error (+ sexp-column lisp-body-indent)))))
  665. (let ((l '((block 1)
  666. (case (4 &rest (&whole 2 &rest 1)))
  667. (ccase . case)
  668. (ecase . case)
  669. (typecase . case)
  670. (etypecase . case)
  671. (ctypecase . case)
  672. (catch 1)
  673. (cond (&rest (&whole 2 &rest 1)))
  674. (defvar (4 2 2))
  675. (defclass (6 4 (&whole 2 &rest 1) (&whole 2 &rest 1)))
  676. (defconstant . defvar)
  677. (defcustom (4 2 2 2))
  678. (defparameter . defvar)
  679. (defconst . defcustom)
  680. (define-condition . defclass)
  681. (define-modify-macro (4 &lambda &body))
  682. (defsetf (4 &lambda 4 &body))
  683. (defun (4 &lambda &body))
  684. (defgeneric (4 &lambda &body))
  685. (define-setf-method . defun)
  686. (define-setf-expander . defun)
  687. (defmacro . defun)
  688. (defsubst . defun)
  689. (deftype . defun)
  690. (defmethod lisp-indent-defmethod)
  691. (defpackage (4 2))
  692. (defstruct ((&whole 4 &rest (&whole 2 &rest 1))
  693. &rest (&whole 2 &rest 1)))
  694. (destructuring-bind
  695. ((&whole 6 &rest 1) 4 &body))
  696. (do lisp-indent-do)
  697. (do* . do)
  698. (dolist ((&whole 4 2 1) &body))
  699. (dotimes . dolist)
  700. (eval-when 1)
  701. (flet ((&whole 4 &rest (&whole 1 &lambda &body)) &body))
  702. (labels . flet)
  703. (macrolet . flet)
  704. (generic-flet . flet)
  705. (generic-labels . flet)
  706. (handler-case (4 &rest (&whole 2 &lambda &body)))
  707. (restart-case . handler-case)
  708. ;; `else-body' style
  709. (if (nil nil &body))
  710. ;; single-else style (then and else equally indented)
  711. (if (&rest nil))
  712. (lambda (&lambda &rest lisp-indent-function-lambda-hack))
  713. (let ((&whole 4 &rest (&whole 1 1 2)) &body))
  714. (let* . let)
  715. (compiler-let . let) ;barf
  716. (handler-bind . let)
  717. (restart-bind . let)
  718. (locally 1)
  719. ;(loop lisp-indent-loop)
  720. (:method (&lambda &body)) ; in `defgeneric'
  721. (multiple-value-bind ((&whole 6 &rest 1) 4 &body))
  722. (multiple-value-call (4 &body))
  723. (multiple-value-prog1 1)
  724. (multiple-value-setq (4 2))
  725. (multiple-value-setf . multiple-value-setq)
  726. (pprint-logical-block (4 2))
  727. (print-unreadable-object ((&whole 4 1 &rest 1) &body))
  728. ;; Combines the worst features of BLOCK, LET and TAGBODY
  729. (prog (&lambda &rest lisp-indent-tagbody))
  730. (prog* . prog)
  731. (prog1 1)
  732. (prog2 2)
  733. (progn 0)
  734. (progv (4 4 &body))
  735. (return 0)
  736. (return-from (nil &body))
  737. (symbol-macrolet . let)
  738. (tagbody lisp-indent-tagbody)
  739. (throw 1)
  740. (unless 1)
  741. (unwind-protect (5 &body))
  742. (when 1)
  743. (with-accessors . multiple-value-bind)
  744. (with-condition-restarts . multiple-value-bind)
  745. (with-compilation-unit (&lambda &body))
  746. (with-output-to-string (4 2))
  747. (with-slots . multiple-value-bind)
  748. (with-standard-io-syntax (2)))))
  749. (dolist (el l)
  750. (put (car el) 'common-lisp-indent-function
  751. (if (symbolp (cdr el))
  752. (get (cdr el) 'common-lisp-indent-function)
  753. (car (cdr el))))))
  754. ;; In elisp, the else part of `if' is in an implicit progn, so indent
  755. ;; it more.
  756. (put 'if 'common-lisp-indent-function-for-elisp 2)
  757. (put 'with-output-to-string 'common-lisp-indent-function-for-elisp 0)
  758. ;(defun foo (x)
  759. ; (tagbody
  760. ; foo
  761. ; (bar)
  762. ; baz
  763. ; (when (losing)
  764. ; (with-big-loser
  765. ; (yow)
  766. ; ((lambda ()
  767. ; foo)
  768. ; big)))
  769. ; (flet ((foo (bar baz zap)
  770. ; (zip))
  771. ; (zot ()
  772. ; quux))
  773. ; (do ()
  774. ; ((lose)
  775. ; (foo 1))
  776. ; (quux)
  777. ; foo
  778. ; (lose))
  779. ; (cond ((x)
  780. ; (win 1 2
  781. ; (foo)))
  782. ; (t
  783. ; (lose
  784. ; 3))))))
  785. ;(put 'while 'common-lisp-indent-function 1)
  786. ;(put 'defwrapper'common-lisp-indent-function ...)
  787. ;(put 'def 'common-lisp-indent-function ...)
  788. ;(put 'defflavor 'common-lisp-indent-function ...)
  789. ;(put 'defsubst 'common-lisp-indent-function ...)
  790. ;(put 'with-restart 'common-lisp-indent-function '((1 4 ((* 1))) (2 &body)))
  791. ;(put 'restart-case 'common-lisp-indent-function '((1 4) (* 2 ((0 1) (* 1)))))
  792. ;(put 'define-condition 'common-lisp-indent-function '((1 6) (2 6 ((&whole 1))) (3 4 ((&whole 1))) (4 &body)))
  793. ;(put 'with-condition-handler 'common-lisp-indent-function '((1 4 ((* 1))) (2 &body)))
  794. ;(put 'condition-case 'common-lisp-indent-function '((1 4) (* 2 ((0 1) (1 3) (2 &body)))))
  795. ;(put 'defclass 'common-lisp-indent-function '((&whole 2 &rest (&whole 2 &rest 1) &rest (&whole 2 &rest 1)))
  796. ;(put 'defgeneric 'common-lisp-indent-function 'defun)
  797. (provide 'cl-indent)
  798. ;;; cl-indent.el ends here