X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c23670f81e059ebe645c88575f4ddfa67f26bf6b..c66cd0ff658dfcba849176d58a405c69e9672e80:/lisp/emacs-lisp/cl-indent.el diff --git a/lisp/emacs-lisp/cl-indent.el b/lisp/emacs-lisp/cl-indent.el index c5e13a4c00..d52c487917 100644 --- a/lisp/emacs-lisp/cl-indent.el +++ b/lisp/emacs-lisp/cl-indent.el @@ -1,6 +1,7 @@ ;;; cl-indent.el --- enhanced lisp-indent mode -;; Copyright (C) 1987, 2000, 2001, 2002 Free Software Foundation, Inc. +;; Copyright (C) 1987, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, +;; 2008, 2009 Free Software Foundation, Inc. ;; Author: Richard Mlynarik ;; Created: July 1987 @@ -9,10 +10,10 @@ ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,9 +21,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -49,25 +48,25 @@ ;;; Code: (defgroup lisp-indent nil - "Indentation in Lisp" + "Indentation in Lisp." :group 'lisp) (defcustom lisp-indent-maximum-backtracking 3 - "*Maximum depth to backtrack out from a sublist for structured indentation. -If this variable is 0, no backtracking will occur and forms such as flet + "Maximum depth to backtrack out from a sublist for structured indentation. +If this variable is 0, no backtracking will occur and forms such as `flet' may not be correctly indented." :type 'integer :group 'lisp-indent) (defcustom lisp-tag-indentation 1 - "*Indentation of tags relative to containing list. + "Indentation of tags relative to containing list. This variable is used by the function `lisp-indent-tagbody'." :type 'integer :group 'lisp-indent) (defcustom lisp-tag-body-indentation 3 - "*Indentation of non-tagged lines relative to containing list. + "Indentation of non-tagged lines relative to containing list. This variable is used by the function `lisp-indent-tagbody' to indent normal lines (lines without tags). The indentation is relative to the indentation of the parenthesis enclosing @@ -79,32 +78,32 @@ by `lisp-body-indent'." :group 'lisp-indent) (defcustom lisp-backquote-indentation t - "*Whether or not to indent backquoted lists as code. + "Whether or not to indent backquoted lists as code. If nil, indent backquoted lists as data, i.e., like quoted lists." :type 'boolean :group 'lisp-indent) (defcustom lisp-loop-keyword-indentation 3 - "*Indentation of loop keywords in extended loop forms." + "Indentation of loop keywords in extended loop forms." :type 'integer :group 'lisp-indent) (defcustom lisp-loop-forms-indentation 5 - "*Indentation of forms in extended loop forms." + "Indentation of forms in extended loop forms." :type 'integer :group 'lisp-indent) (defcustom lisp-simple-loop-indentation 3 - "*Indentation of forms in simple loop forms." + "Indentation of forms in simple loop forms." :type 'integer :group 'lisp-indent) -(defvar lisp-indent-error-function) -(defvar lisp-indent-defun-method '(4 &lambda &body)) +(defvar lisp-indent-defun-method '(4 &lambda &body) + "Indentation for function with `common-lisp-indent-function' property `defun'.") (defun extended-loop-p (loop-start) @@ -136,6 +135,75 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." ;;;###autoload (defun common-lisp-indent-function (indent-point state) + "Function to indent the arguments of a Lisp function call. +This is suitable for use as the value of the variable +`lisp-indent-function'. INDENT-POINT is the point at which the +indentation function is called, and STATE is the +`parse-partial-sexp' state at that position. Browse the +`lisp-indent' customize group for options affecting the behavior +of this function. + +If the indentation point is in a call to a Lisp function, that +function's common-lisp-indent-function property specifies how +this function should indent it. Possible values for this +property are: + +* defun, meaning indent according to `lisp-indent-defun-method'; + i.e., like (4 &lambda &body), as explained below. + +* any other symbol, meaning a function to call. The function should + take the arguments: PATH STATE INDENT-POINT SEXP-COLUMN NORMAL-INDENT. + PATH is a list of integers describing the position of point in terms of + list-structure with respect to the containing lists. For example, in + ((a b c (d foo) f) g), foo has a path of (0 3 1). In other words, + to reach foo take the 0th element of the outermost list, then + the 3rd element of the next list, and finally the 1st element. + STATE and INDENT-POINT are as in the arguments to + `common-lisp-indent-function'. SEXP-COLUMN is the column of + the open parenthesis of the innermost containing list. + NORMAL-INDENT is the column the indentation point was + originally in. This function should behave like `lisp-indent-259'. + +* an integer N, meaning indent the first N arguments like + function arguments, and any further arguments like a body. + This is equivalent to (4 4 ... &body). + +* a list. The list element in position M specifies how to indent the Mth + function argument. If there are fewer elements than function arguments, + the last list element applies to all remaining arguments. The accepted + list elements are: + + * nil, meaning the default indentation. + + * an integer, specifying an explicit indentation. + + * &lambda. Indent the argument (which may be a list) by 4. + + * &rest. When used, this must be the penultimate element. The + element after this one applies to all remaining arguments. + + * &body. This is equivalent to &rest lisp-body-indent, i.e., indent + all remaining elements by `lisp-body-indent'. + + * &whole. This must be followed by nil, an integer, or a + function symbol. This indentation is applied to the + associated argument, and as a base indent for all remaining + arguments. For example, an integer P means indent this + argument by P, and all remaining arguments by P, plus the + value specified by their associated list element. + + * a symbol. A function to call, with the 6 arguments specified above. + + * a list, with elements as described above. This applies when the + associated function argument is itself a list. Each element of the list + specifies how to indent the associated argument. + +For example, the function `case' has an indent property +\(4 &rest (&whole 2 &rest 1)), meaning: + * indent the first argument by 4. + * arguments after the first should be lists, and there may be any number + of them. The first list element has an offset of 2, all the rest + have an offset of 2+1=3." (if (save-excursion (goto-char (elt state 1)) (looking-at "([Ll][Oo][Oo][Pp]")) (common-lisp-loop-part-indentation indent-point state) @@ -150,6 +218,7 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." ;; Path describes the position of point in terms of ;; list-structure with respect to containing lists. ;; `foo' has a path of (0 4 1) in `((a b c (d foo) f) g)' + ;; (Surely (0 3 1)?). (path ()) ;; set non-nil when somebody works out the indentation to use calculated @@ -304,6 +373,9 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." (lisp-indent-259 method path state indent-point sexp-column normal-indent)))) +;; Dynamically bound in common-lisp-indent-call-method. +(defvar lisp-indent-error-function) + (defun lisp-indent-report-bad-format (m) (error "%s has a badly-formed %s property: %s" ;; Love those free variable references!! @@ -372,14 +444,16 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." ;; Too few elements in pattern. (throw 'exit normal-indent))) ((eq tem 'nil) - (throw 'exit (list normal-indent containing-form-start))) - ((eq tem '&lambda) - (throw 'exit - (cond ((null p) - (list (+ sexp-column 4) containing-form-start)) - ((null (cdr p)) - (+ sexp-column 1)) - (t normal-indent)))) + (throw 'exit (if (consp normal-indent) + normal-indent + (list normal-indent containing-form-start)))) + ((eq tem '&lambda) + (throw 'exit + (cond ((null p) + (list (+ sexp-column 4) containing-form-start)) + ((null (cdr p)) + (+ sexp-column 1)) + (t normal-indent)))) ((integerp tem) (throw 'exit (if (null p) ;not in subforms @@ -458,7 +532,7 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." (forward-char 1) (forward-sexp 3) (backward-sexp) - (looking-at ":"))) + (looking-at ":\\|\\sw+"))) '(4 4 (&whole 4 &rest 4) &body) (get 'defun 'common-lisp-indent-function)) path state indent-point sexp-column normal-indent)) @@ -486,8 +560,11 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." (let ((l '((block 1) (case (4 &rest (&whole 2 &rest 1))) - (ccase . case) (ecase . case) - (typecase . case) (etypecase . case) (ctypecase . case) + (ccase . case) + (ecase . case) + (typecase . case) + (etypecase . case) + (ctypecase . case) (catch 1) (cond (&rest (&whole 2 &rest 1))) (defvar (4 2 2)) @@ -502,7 +579,9 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." (defun (4 &lambda &body)) (define-setf-method . defun) (define-setf-expander . defun) - (defmacro . defun) (defsubst . defun) (deftype . defun) + (defmacro . defun) + (defsubst . defun) + (deftype . defun) (defmethod lisp-indent-defmethod) (defpackage (4 2)) (defstruct ((&whole 4 &rest (&whole 2 &rest 1)) @@ -517,7 +596,8 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." (flet ((&whole 4 &rest (&whole 1 &lambda &body)) &body)) (labels . flet) (macrolet . flet) - (generic-flet . flet) (generic-labels . flet) + (generic-flet . flet) + (generic-labels . flet) (handler-case (4 &rest (&whole 2 &lambda &body))) (restart-case . handler-case) ;; `else-body' style @@ -528,7 +608,8 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." (let ((&whole 4 &rest (&whole 1 1 2)) &body)) (let* . let) (compiler-let . let) ;barf - (handler-bind . let) (restart-bind . let) + (handler-bind . let) + (restart-bind . let) (locally 1) ;(loop lisp-indent-loop) (:method (&lambda &body)) ; in `defgeneric' @@ -609,5 +690,5 @@ If nil, indent backquoted lists as data, i.e., like quoted lists." ;(put 'defclass 'common-lisp-indent-function '((&whole 2 &rest (&whole 2 &rest 1) &rest (&whole 2 &rest 1))) ;(put 'defgeneric 'common-lisp-indent-function 'defun) -;;; arch-tag: 7914d50f-92ec-4476-93fc-0f043a380e03 +;; arch-tag: 7914d50f-92ec-4476-93fc-0f043a380e03 ;;; cl-indent.el ends here