Annotation of 43BSDReno/contrib/emacs-18.55/lisp/cl-indent.el, revision 1.1

1.1     ! root        1: ;; Lisp mode, and its idiosyncratic commands.
        !             2: ;; Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: ;; Written by Richard Mlynarik July 1987
        !             4: 
        !             5: ;; This file is part of GNU Emacs.
        !             6: 
        !             7: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             8: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             9: ;; accepts responsibility to anyone for the consequences of using it
        !            10: ;; or for whether it serves any particular purpose or works at all,
        !            11: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            12: ;; License for full details.
        !            13: 
        !            14: ;; Everyone is granted permission to copy, modify and redistribute
        !            15: ;; GNU Emacs, but only under the conditions described in the
        !            16: ;; GNU Emacs General Public License.   A copy of this license is
        !            17: ;; supposed to have been given to you along with GNU Emacs so you
        !            18: ;; can know your rights and responsibilities.  It should be in a
        !            19: ;; file named COPYING.  Among other things, the copyright notice
        !            20: ;; and this notice must be preserved on all copies.
        !            21: 
        !            22: ;;>> TODO
        !            23: ;; :foo
        !            24: ;;   bar
        !            25: ;; :baz
        !            26: ;;   zap
        !            27: ;; &key (like &body)??
        !            28: 
        !            29: ;; &rest 1 in lambda-lists doesn't work
        !            30: ;;  -- really want (foo bar
        !            31: ;;                  baz)
        !            32: ;;     not (foo bar
        !            33: ;;              baz)
        !            34: ;;  Need something better than &rest for such cases
        !            35: 
        !            36: 
        !            37: ;;; Hairy lisp indentation.
        !            38: 
        !            39: (defvar lisp-indent-maximum-backtracking 3
        !            40:   "*Maximum depth to backtrack out from a sublist for structured indentation.
        !            41: If this variable is  0, no backtracking will occur and forms such as  flet
        !            42: may not be correctly indented.")
        !            43: 
        !            44: (defvar lisp-tag-indentation 1
        !            45:   "*Indentation of tags relative to containing list.
        !            46: This variable is used by the function  lisp-indent-tagbody.")
        !            47: 
        !            48: (defvar lisp-tag-body-indentation 3
        !            49:   "*Indentation of non-tagged lines relative to containing list.
        !            50: This variable is used by the function  lisp-indent-tagbody  to indent normal
        !            51: lines (lines without tags).
        !            52: The indentation is relative to the indentation of the parenthesis enclosing
        !            53: he special form.  If the value is  t, the body of tags will be indented
        !            54: as a block at the same indentation as the first s-expression following
        !            55: the tag.  In this case, any forms before the first tag are indented
        !            56: by lisp-body-indent.")
        !            57: 
        !            58: 
        !            59: (defun common-lisp-indent-hook (indent-point state)
        !            60:   (let ((normal-indent (current-column)))
        !            61:     ;; Walk up list levels until we see something
        !            62:     ;;  which does special things with subforms.
        !            63:     (let ((depth 0)
        !            64:           ;; Path describes the position of point in terms of
        !            65:           ;;  list-structure with respect to contining lists.
        !            66:           ;; `foo' has a path of (0 4 1) in `((a b c (d foo) f) g)'
        !            67:           (path ())
        !            68:           ;; set non-nil when somebody works out the indentation to use
        !            69:           calculated
        !            70:           (last-point indent-point)
        !            71:           ;; the position of the open-paren of the innermost containing list
        !            72:           (containing-form-start (elt state 1))
        !            73:           ;; the column of the above
        !            74:           sexp-column)
        !            75:       ;; Move to start of innermost containing list
        !            76:       (goto-char containing-form-start)
        !            77:       (setq sexp-column (current-column))
        !            78:       ;; Look over successively less-deep containing forms
        !            79:       (while (and (not calculated)
        !            80:                   (< depth lisp-indent-maximum-backtracking))
        !            81:         (let ((containing-sexp (point)))
        !            82:           (forward-char 1)
        !            83:           (parse-partial-sexp (point) indent-point 1 t)
        !            84:           ;; Move to the car of the relevant containing form
        !            85:           (let (tem function method)
        !            86:             (if (not (looking-at "\\sw\\|\\s_"))
        !            87:                 ;; This form doesn't seem to start with a symbol
        !            88:                 (setq function nil method nil)
        !            89:               (setq tem (point))
        !            90:               (forward-sexp 1)
        !            91:               (setq function (downcase (buffer-substring tem (point))))
        !            92:               (goto-char tem)
        !            93:               (setq tem (intern-soft function)
        !            94:                     method (get tem 'common-lisp-indent-hook))
        !            95:               (cond ((and (null method)
        !            96:                           (string-match ":[^:]+" function))
        !            97:                      ;; The pleblisp package feature
        !            98:                      (setq function (substring function
        !            99:                                                (1+ (match-beginning 0)))
        !           100:                            method (get (intern-soft function)
        !           101:                                        'common-lisp-indent-hook)))
        !           102:                     ((and (null method))
        !           103:                      ;; backwards compatibility
        !           104:                      (setq method (get tem 'lisp-indent-hook)))))
        !           105:             (let ((n 0))
        !           106:               ;; How far into the containing form is the current form?
        !           107:               (if (< (point) indent-point)
        !           108:                   (while (condition-case ()
        !           109:                              (progn
        !           110:                                (forward-sexp 1)
        !           111:                                (if (>= (point) indent-point)
        !           112:                                    nil
        !           113:                                  (parse-partial-sexp (point)
        !           114:                                                      indent-point 1 t)
        !           115:                                  (setq n (1+ n))
        !           116:                                  t))
        !           117:                            (error nil))))
        !           118:               (setq path (cons n path)))
        !           119: 
        !           120:             ;; backwards compatibility.
        !           121:             (cond ((null function))
        !           122:                   ((null method)
        !           123:                    (if (null (cdr path))
        !           124:                        ;; (package prefix was stripped off above)
        !           125:                        (setq method (cond ((string-match "\\`def"
        !           126:                                                          function)
        !           127:                                            '(4 (&whole 4 &rest 1) &body))
        !           128:                                           ((string-match "\\`\\(with\\|do\\)-"
        !           129:                                                          function)
        !           130:                                            '(4 &body))))))
        !           131:                   ;; backwards compatibility.  Bletch.
        !           132:                   ((eq method 'defun)
        !           133:                    (setq method '(4 (&whole 4 &rest 1) &body))))
        !           134: 
        !           135:             (cond ((and (memq (char-after (1- containing-sexp)) '(?\' ?\`))
        !           136:                         (not (eql (char-after (- containing-sexp 2)) ?\#)))
        !           137:                    ;; No indentation for "'(...)" elements
        !           138:                    (setq calculated (1+ sexp-column)))
        !           139:                   ((eql (char-after (1- containing-sexp)) ?\#)
        !           140:                    ;; "#(...)"
        !           141:                    (setq calculated (1+ sexp-column)))
        !           142:                   ((null method))
        !           143:                   ((integerp method)
        !           144:                    ;; convenient top-level hack.
        !           145:                    ;;  (also compatible with lisp-indent-hook)
        !           146:                    ;; The number specifies how many `distinguished'
        !           147:                    ;;  forms there are before the body starts
        !           148:                    ;; Equivalent to (4 4 ... &body)
        !           149:                    (setq calculated (cond ((cdr path)
        !           150:                                            normal-indent)
        !           151:                                           ((<= (car path) method)
        !           152:                                            ;; `distinguished' form
        !           153:                                            (list (+ sexp-column 4)
        !           154:                                                  containing-form-start))
        !           155:                                           ((= (car path) (1+ method))
        !           156:                                            ;; first body form.
        !           157:                                            (+ sexp-column lisp-body-indent))
        !           158:                                           (t
        !           159:                                            ;; other body form
        !           160:                                            normal-indent))))
        !           161:                   ((symbolp method)
        !           162:                    (setq calculated (funcall method
        !           163:                                              path state indent-point
        !           164:                                              sexp-column normal-indent)))
        !           165:                   (t
        !           166:                    (setq calculated (lisp-indent-259
        !           167:                                       method path state indent-point
        !           168:                                       sexp-column normal-indent)))))
        !           169:           (goto-char containing-sexp)
        !           170:           (setq last-point containing-sexp)
        !           171:           (if (not calculated)
        !           172:               (condition-case ()
        !           173:                    (progn (backward-up-list 1)
        !           174:                           (setq depth (1+ depth)))
        !           175:                 (error (setq depth lisp-indent-maximum-backtracking))))))
        !           176:       calculated)))
        !           177: 
        !           178: 
        !           179: (defun lisp-indent-report-bad-format (m)
        !           180:   (error "%s has a badly-formed %s property: %s"
        !           181:          ;; Love them free variable references!!
        !           182:          function 'common-lisp-indent-hook m))
        !           183: 
        !           184: ;; Blame the crufty control structure on dynamic scoping
        !           185: ;;  -- not on me!
        !           186: (defun lisp-indent-259 (method path state indent-point
        !           187:                         sexp-column normal-indent)
        !           188:   (catch 'exit
        !           189:     (let ((p path)
        !           190:           (containing-form-start (elt state 1))
        !           191:           n tem tail)
        !           192:       ;; Isn't tail-recursion wonderful?
        !           193:       (while p
        !           194:         ;; This while loop is for destructuring.
        !           195:         ;; p is set to (cdr p) each iteration.
        !           196:         (if (not (consp method)) (lisp-indent-report-bad-format method))
        !           197:         (setq n (1- (car p))
        !           198:               p (cdr p)
        !           199:               tail nil)
        !           200:         (while n
        !           201:           ;; This while loop is for advancing along a method
        !           202:           ;; until the relevant (possibly &rest/&body) pattern
        !           203:           ;; is reached.
        !           204:           ;; n is set to (1- n) and method to (cdr method)
        !           205:           ;; each iteration.
        !           206: ; (message "trying %s for %s %s" method p function) (sit-for 1)
        !           207:           (setq tem (car method))
        !           208: 
        !           209:           (or (eq tem 'nil)             ;default indentation
        !           210: ;             (eq tem '&lambda)         ;abbrev for (&whole 4 (&rest 1))
        !           211:               (and (eq tem '&body) (null (cdr method)))
        !           212:               (and (eq tem '&rest)
        !           213:                    (consp (cdr method)) (null (cdr (cdr method))))
        !           214:               (integerp tem)            ;explicit indentation specified
        !           215:               (and (consp tem)          ;destructuring
        !           216:                    (eq (car tem) '&whole)
        !           217:                    (or (symbolp (car (cdr tem)))
        !           218:                        (integerp (car (cdr tem)))))
        !           219:               (and (symbolp tem)        ;a function to call to do the work.
        !           220:                    (null (cdr method)))
        !           221:               (lisp-indent-report-bad-format method))
        !           222: 
        !           223:           (cond ((and tail (not (consp tem)))
        !           224:                  ;; indent tail of &rest in same way as first elt of rest
        !           225:                  (throw 'exit normal-indent))
        !           226:                 ((eq tem '&body)
        !           227:                  ;; &body means (&rest <lisp-body-indent>)
        !           228:                  (throw 'exit
        !           229:                    (if (and (= n 0)     ;first body form
        !           230:                             (null p))   ;not in subforms
        !           231:                        (+ sexp-column
        !           232:                           lisp-body-indent)
        !           233:                        normal-indent)))
        !           234:                 ((eq tem '&rest)
        !           235:                  ;; this pattern holds for all remaining forms
        !           236:                  (setq tail (> n 0)
        !           237:                        n 0
        !           238:                        method (cdr method)))
        !           239:                 ((> n 0)
        !           240:                  ;; try next element of pattern
        !           241:                  (setq n (1- n)
        !           242:                        method (cdr method))
        !           243:                  (if (< n 0)
        !           244:                      ;; Too few elements in pattern.
        !           245:                      (throw 'exit normal-indent)))
        !           246:                 ((eq tem 'nil)
        !           247:                  (throw 'exit (list normal-indent containing-form-start)))
        !           248: ;               ((eq tem '&lambda)
        !           249: ;                ;; abbrev for (&whole 4 &rest 1)
        !           250: ;                (throw 'exit
        !           251: ;                  (cond ((null p)
        !           252: ;                         (list (+ sexp-column 4) containing-form-start))
        !           253: ;                        ((null (cdr p))
        !           254: ;                         (+ sexp-column 1))
        !           255: ;                        (t normal-indent))))
        !           256:                 ((integerp tem)
        !           257:                  (throw 'exit
        !           258:                    (if (null p)         ;not in subforms
        !           259:                        (list (+ sexp-column tem) containing-form-start)
        !           260:                        normal-indent)))
        !           261:                 ((symbolp tem)          ;a function to call
        !           262:                  (throw 'exit
        !           263:                    (funcall tem path state indent-point
        !           264:                             sexp-column normal-indent)))
        !           265:                 (t
        !           266:                  ;; must be a destructing frob
        !           267:                  (if (not (null p))
        !           268:                      ;; descend
        !           269:                      (setq method (cdr (cdr tem))
        !           270:                            n nil)
        !           271:                    (setq tem (car (cdr tem)))
        !           272:                    (throw 'exit
        !           273:                      (cond (tail
        !           274:                             normal-indent)
        !           275:                            ((eq tem 'nil)
        !           276:                             (list normal-indent
        !           277:                                   containing-form-start))
        !           278:                            ((integerp tem)
        !           279:                             (list (+ sexp-column tem)
        !           280:                                   containing-form-start))
        !           281:                            (t
        !           282:                             (funcall tem path state indent-point
        !           283:                                      sexp-column normal-indent))))))))))))
        !           284: 
        !           285: (defun lisp-indent-tagbody (path state indent-point sexp-column normal-indent)
        !           286:   (if (not (null (cdr path)))
        !           287:       normal-indent
        !           288:     (save-excursion
        !           289:       (goto-char indent-point)
        !           290:       (beginning-of-line)
        !           291:       (skip-chars-forward " \t")
        !           292:       (list (cond ((looking-at "\\sw\\|\\s_")
        !           293:                    ;; a tagbody tag
        !           294:                    (+ sexp-column lisp-tag-indentation))
        !           295:                   ((integerp lisp-tag-body-indentation)
        !           296:                    (+ sexp-column lisp-tag-body-indentation))
        !           297:                   ((eq lisp-tag-body-indentation 't)
        !           298:                    (condition-case ()
        !           299:                        (progn (backward-sexp 1) (current-column))
        !           300:                      (error (1+ sexp-column))))
        !           301:                   (t (+ sexp-column lisp-body-indent)))
        !           302: ;            (cond ((integerp lisp-tag-body-indentation)
        !           303: ;                   (+ sexp-column lisp-tag-body-indentation))
        !           304: ;                  ((eq lisp-tag-body-indentation 't)
        !           305: ;                   normal-indent)
        !           306: ;                  (t
        !           307: ;                   (+ sexp-column lisp-body-indent)))
        !           308:             (elt state 1)
        !           309:             ))))
        !           310: 
        !           311: (defun lisp-indent-do (path state indent-point sexp-column normal-indent)
        !           312:   (if (>= (car path) 3)
        !           313:       (let ((lisp-tag-body-indentation lisp-body-indent))
        !           314:         (funcall (function lisp-indent-tagbody)
        !           315:                 path state indent-point sexp-column normal-indent))
        !           316:     (funcall (function lisp-indent-259)
        !           317:             '((&whole nil &rest
        !           318:                ;; the following causes wierd indentation
        !           319:                ;;(&whole 1 1 2 nil)
        !           320:                )
        !           321:               (&whole nil &rest 1))
        !           322:             path state indent-point sexp-column normal-indent)))
        !           323: 
        !           324: (defun lisp-indent-function-lambda-hack (path state indent-point
        !           325:                                          sexp-column normal-indent)
        !           326:   ;; indent (function (lambda () <newline> <body-forms>)) kludgily.
        !           327:   (if (or (cdr path) ; wtf?
        !           328:           (> (car path) 3))
        !           329:       ;; line up under previous body form
        !           330:       normal-indent
        !           331:     ;; line up under function rather than under lambda in order to
        !           332:     ;;  conserve horizontal space.  (Which is what #' is for.)
        !           333:     (condition-case ()
        !           334:         (save-excursion
        !           335:           (backward-up-list 2)
        !           336:           (forward-char 1)
        !           337:           (if (looking-at "\\(lisp:+\\)?function\\(\\Sw\\|\\S_\\)")
        !           338:               (+ lisp-body-indent -1 (current-column))
        !           339:               (+ sexp-column lisp-body-indent)))
        !           340:        (error (+ sexp-column lisp-body-indent)))))
        !           341: 
        !           342: 
        !           343: (let ((l '((block 1)
        !           344:           (catch 1)
        !           345:            (case        (4 &rest (&whole 2 &rest 1)))
        !           346:            (ccase . case) (ecase . case)
        !           347:            (typecase . case) (etypecase . case) (ctypecase . case)
        !           348:            (catch 1)
        !           349:            (cond        (&rest (&whole 2 &rest 1)))
        !           350:            (block 1)
        !           351:            (defvar      (4 2 2))
        !           352:            (defconstant . defvar) (defparameter . defvar)
        !           353:            (define-modify-macro
        !           354:                         (4 &body))
        !           355:            (define-setf-method
        !           356:                         (4 (&whole 4 &rest 1) &body))
        !           357:            (defsetf     (4 (&whole 4 &rest 1) 4 &body))
        !           358:            (defun       (4 (&whole 4 &rest 1) &body))
        !           359:            (defmacro . defun) (deftype . defun)
        !           360:            (defstruct   ((&whole 4 &rest (&whole 2 &rest 1))
        !           361:                          &rest (&whole 2 &rest 1)))
        !           362:            (destructuring-bind
        !           363:                         ((&whole 6 &rest 1) 4 &body))
        !           364:            (do          lisp-indent-do)
        !           365:            (do* . do)
        !           366:            (dolist      ((&whole 4 2 1) &body))
        !           367:            (dotimes . dolist)
        !           368:            (eval-when  1)
        !           369:            (flet        ((&whole 4 &rest (&whole 1 (&whole 4 &rest 1) &body))
        !           370:                          &body))
        !           371:            (labels . flet)
        !           372:            (macrolet . flet)
        !           373:            ;; `else-body' style
        !           374:            (if          (nil nil &body))
        !           375:            ;; single-else style (then and else equally indented)
        !           376:            (if          (&rest nil))
        !           377:            ;(lambda     ((&whole 4 &rest 1) &body))
        !           378:            (lambda      ((&whole 4 &rest 1)
        !           379:                          &rest lisp-indent-function-lambda-hack))
        !           380:            (let         ((&whole 4 &rest (&whole 1 1 2)) &body))
        !           381:            (let* . let)
        !           382:            (locally    1)
        !           383:            ;(loop ...)
        !           384:            (multiple-value-bind
        !           385:                         ((&whole 6 &rest 1) 4 &body))
        !           386:            (multiple-value-call
        !           387:                        (4 &body))
        !           388:            (multiple-value-list 1)
        !           389:            (multiple-value-prog1 1)
        !           390:            (multiple-value-setq
        !           391:                        (4 2))
        !           392:            ;; Combines the worst features of BLOCK, LET and TAGBODY
        !           393:            (prog        ((&whole 4 &rest 1) &rest lisp-indent-tagbody))
        !           394:            (prog* . prog)
        !           395:            (prog1 1)
        !           396:            (prog2 2)
        !           397:            (progn 0)
        !           398:            (progv       (4 4 &body))
        !           399:            (return 0)
        !           400:            (return-from (nil &body))
        !           401:            (tagbody     lisp-indent-tagbody)
        !           402:            (throw 1)
        !           403:            (unless 1)
        !           404:            (unwind-protect
        !           405:                         (5 &body))
        !           406:            (when 1))))
        !           407:   (while l
        !           408:     (put (car (car l)) 'common-lisp-indent-hook
        !           409:          (if (symbolp (cdr (car l)))
        !           410:              (get (cdr (car l)) 'common-lisp-indent-hook)
        !           411:              (car (cdr (car l)))))
        !           412:     (setq l (cdr l))))
        !           413: 
        !           414: 
        !           415: ;(defun foo (x)
        !           416: ;  (tagbody
        !           417: ;   foo
        !           418: ;     (bar)
        !           419: ;   baz
        !           420: ;     (when (losing)
        !           421: ;       (with-big-loser
        !           422: ;           (yow)
        !           423: ;         ((lambda ()
        !           424: ;            foo)
        !           425: ;          big)))
        !           426: ;     (flet ((foo (bar baz zap)
        !           427: ;              (zip))
        !           428: ;            (zot ()
        !           429: ;              quux))
        !           430: ;       (do ()
        !           431: ;           ((lose)
        !           432: ;            (foo 1))
        !           433: ;         (quux)
        !           434: ;        foo
        !           435: ;         (lose))
        !           436: ;       (cond ((x)
        !           437: ;              (win 1 2
        !           438: ;                   (foo)))
        !           439: ;             (t
        !           440: ;              (lose
        !           441: ;                3))))))
        !           442:           
        !           443: 
        !           444: ;(put 'while    'common-lisp-indent-hook 1)
        !           445: ;(put 'defwrapper'common-lisp-indent-hook ...)
        !           446: ;(put 'def 'common-lisp-indent-hook ...)
        !           447: ;(put 'defflavor        'common-lisp-indent-hook ...)
        !           448: ;(put 'defsubst 'common-lisp-indent-hook ...)
        !           449: 
        !           450: ;;(put 'define-restart-name 'common-lisp-indent-hook '1)
        !           451: ;(put 'with-restart 'common-lisp-indent-hook '((1 4 ((* 1))) (2 &body)))
        !           452: ;(put 'restart-case 'common-lisp-indent-hook '((1 4) (* 2 ((0 1) (* 1)))))
        !           453: ;(put 'define-condition 'common-lisp-indent-hook '((1 6) (2 6 ((* 1))) (3 4 ((* 1))) (4 &body)))
        !           454: ;(put 'with-condition-handler 'common-lisp-indent-hook '((1 4 ((* 1))) (2 &body)))
        !           455: ;(put 'condition-case 'common-lisp-indent-hook '((1 4) (* 2 ((0 1) (1 3) (2 &body)))))
        !           456: 
        !           457: 
        !           458: ;;;; Turn it on.
        !           459: ;(setq lisp-indent-hook 'common-lisp-indent-hook)
        !           460: 
        !           461: ;; To disable this stuff, (setq lisp-indent-hook 'lisp-indent-hook)
        !           462: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.