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

1.1     ! root        1: ;; Lisp mode, and its idiosyncratic commands.
        !             2: ;; Copyright (C) 1985 Free Software Foundation, Inc.
        !             3: 
        !             4: ;; This file is part of GNU Emacs.
        !             5: 
        !             6: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             7: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: ;; accepts responsibility to anyone for the consequences of using it
        !             9: ;; or for whether it serves any particular purpose or works at all,
        !            10: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: ;; License for full details.
        !            12: 
        !            13: ;; Everyone is granted permission to copy, modify and redistribute
        !            14: ;; GNU Emacs, but only under the conditions described in the
        !            15: ;; GNU Emacs General Public License.   A copy of this license is
        !            16: ;; supposed to have been given to you along with GNU Emacs so you
        !            17: ;; can know your rights and responsibilities.  It should be in a
        !            18: ;; file named COPYING.  Among other things, the copyright notice
        !            19: ;; and this notice must be preserved on all copies.
        !            20: 
        !            21: 
        !            22: (defvar lisp-mode-syntax-table nil "")
        !            23: (defvar emacs-lisp-mode-syntax-table nil "")
        !            24: (defvar lisp-mode-abbrev-table nil "")
        !            25: 
        !            26: (if (not emacs-lisp-mode-syntax-table)
        !            27:     (let ((i 0))
        !            28:       (setq emacs-lisp-mode-syntax-table (make-syntax-table))
        !            29:       (while (< i ?0)
        !            30:        (modify-syntax-entry i "_   " emacs-lisp-mode-syntax-table)
        !            31:        (setq i (1+ i)))
        !            32:       (setq i (1+ ?9))
        !            33:       (while (< i ?A)
        !            34:        (modify-syntax-entry i "_   " emacs-lisp-mode-syntax-table)
        !            35:        (setq i (1+ i)))
        !            36:       (setq i (1+ ?Z))
        !            37:       (while (< i ?a)
        !            38:        (modify-syntax-entry i "_   " emacs-lisp-mode-syntax-table)
        !            39:        (setq i (1+ i)))
        !            40:       (setq i (1+ ?z))
        !            41:       (while (< i 128)
        !            42:        (modify-syntax-entry i "_   " emacs-lisp-mode-syntax-table)
        !            43:        (setq i (1+ i)))
        !            44:       (modify-syntax-entry ?  "    " emacs-lisp-mode-syntax-table)
        !            45:       (modify-syntax-entry ?\t "    " emacs-lisp-mode-syntax-table)
        !            46:       (modify-syntax-entry ?\n ">   " emacs-lisp-mode-syntax-table)
        !            47:       (modify-syntax-entry ?\f ">   " emacs-lisp-mode-syntax-table)
        !            48:       (modify-syntax-entry ?\; "<   " emacs-lisp-mode-syntax-table)
        !            49:       (modify-syntax-entry ?` "'   " emacs-lisp-mode-syntax-table)
        !            50:       (modify-syntax-entry ?' "'   " emacs-lisp-mode-syntax-table)
        !            51:       (modify-syntax-entry ?, "'   " emacs-lisp-mode-syntax-table)
        !            52:       (modify-syntax-entry ?. "'   " emacs-lisp-mode-syntax-table)
        !            53:       (modify-syntax-entry ?# "'   " emacs-lisp-mode-syntax-table)
        !            54:       (modify-syntax-entry ?\" "\"    " emacs-lisp-mode-syntax-table)
        !            55:       (modify-syntax-entry ?\\ "\\   " emacs-lisp-mode-syntax-table)
        !            56:       (modify-syntax-entry ?\( "()  " emacs-lisp-mode-syntax-table)
        !            57:       (modify-syntax-entry ?\) ")(  " emacs-lisp-mode-syntax-table)
        !            58:       (modify-syntax-entry ?\[ "(]  " emacs-lisp-mode-syntax-table)
        !            59:       (modify-syntax-entry ?\] ")[  " emacs-lisp-mode-syntax-table)))
        !            60: 
        !            61: (define-abbrev-table 'lisp-mode-abbrev-table ())
        !            62: 
        !            63: (defun lisp-mode-variables (lisp-syntax)
        !            64:   (cond (lisp-syntax
        !            65:          (if (not lisp-mode-syntax-table)
        !            66:              (progn (setq lisp-mode-syntax-table
        !            67:                           (copy-syntax-table emacs-lisp-mode-syntax-table))
        !            68:                     (modify-syntax-entry ?\| "\"   "
        !            69:                                          lisp-mode-syntax-table)
        !            70:                     (modify-syntax-entry ?\[ "_   "
        !            71:                                          lisp-mode-syntax-table)
        !            72:                     (modify-syntax-entry ?\] "_   "
        !            73:                                          lisp-mode-syntax-table)))
        !            74:          (set-syntax-table lisp-mode-syntax-table)))
        !            75:   (setq local-abbrev-table lisp-mode-abbrev-table)
        !            76:   (make-local-variable 'paragraph-start)
        !            77:   (setq paragraph-start (concat "^$\\|" page-delimiter))
        !            78:   (make-local-variable 'paragraph-separate)
        !            79:   (setq paragraph-separate paragraph-start)
        !            80:   (make-local-variable 'paragraph-ignore-fill-prefix)
        !            81:   (setq paragraph-ignore-fill-prefix t)
        !            82:   (make-local-variable 'indent-line-function)
        !            83:   (setq indent-line-function 'lisp-indent-line)
        !            84:   (make-local-variable 'comment-start)
        !            85:   (setq comment-start ";")
        !            86:   (make-local-variable 'comment-start-skip)
        !            87:   (setq comment-start-skip ";+ *")
        !            88:   (make-local-variable 'comment-column)
        !            89:   (setq comment-column 40)
        !            90:   (make-local-variable 'comment-indent-hook)
        !            91:   (setq comment-indent-hook 'lisp-comment-indent))
        !            92: 
        !            93: (defun lisp-mode-commands (map)
        !            94:   (define-key map "\e\C-q" 'indent-sexp)
        !            95:   (define-key map "\177" 'backward-delete-char-untabify)
        !            96:   (define-key map "\t" 'lisp-indent-line))
        !            97: 
        !            98: (defvar emacs-lisp-mode-map () "")
        !            99: (if emacs-lisp-mode-map
        !           100:     ()
        !           101:    (setq emacs-lisp-mode-map (make-sparse-keymap))
        !           102:    (define-key emacs-lisp-mode-map "\e\C-x" 'eval-defun)
        !           103:    (lisp-mode-commands emacs-lisp-mode-map))
        !           104: 
        !           105: (defun emacs-lisp-mode ()
        !           106:   "Major mode for editing Lisp code to run in Emacs.
        !           107: Commands:
        !           108: Delete converts tabs to spaces as it moves back.
        !           109: Blank lines separate paragraphs.  Semicolons start comments.
        !           110: \\{emacs-lisp-mode-map}
        !           111: Entry to this mode calls the value of emacs-lisp-mode-hook
        !           112: if that value is non-nil."
        !           113:   (interactive)
        !           114:   (kill-all-local-variables)
        !           115:   (use-local-map emacs-lisp-mode-map)
        !           116:   (set-syntax-table emacs-lisp-mode-syntax-table)
        !           117:   (setq major-mode 'emacs-lisp-mode)
        !           118:   (setq mode-name "Emacs-Lisp")
        !           119:   (lisp-mode-variables nil)
        !           120:   (run-hooks 'emacs-lisp-mode-hook))
        !           121: 
        !           122: (defvar lisp-mode-map ())
        !           123: (if lisp-mode-map
        !           124:     ()
        !           125:   (setq lisp-mode-map (make-sparse-keymap))
        !           126:   (define-key lisp-mode-map "\e\C-x" 'lisp-send-defun)
        !           127:   (define-key lisp-mode-map "\C-c\C-l" 'run-lisp)
        !           128:   (lisp-mode-commands lisp-mode-map))
        !           129: 
        !           130: (defun lisp-mode ()
        !           131:   "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
        !           132: Commands:
        !           133: Delete converts tabs to spaces as it moves back.
        !           134: Blank lines separate paragraphs.  Semicolons start comments.
        !           135: \\{lisp-mode-map}
        !           136: Note that `run-lisp' may be used either to start an inferior Lisp job
        !           137: or to switch back to an existing one.
        !           138: 
        !           139: Entry to this mode calls the value of lisp-mode-hook
        !           140: if that value is non-nil."
        !           141:   (interactive)
        !           142:   (kill-all-local-variables)
        !           143:   (use-local-map lisp-mode-map)
        !           144:   (setq major-mode 'lisp-mode)
        !           145:   (setq mode-name "Lisp")
        !           146:   (lisp-mode-variables t)
        !           147:   (set-syntax-table lisp-mode-syntax-table)
        !           148:   (run-hooks 'lisp-mode-hook))
        !           149: 
        !           150: ;; This will do unless shell.el is loaded.
        !           151: (defun lisp-send-defun nil
        !           152:   "Send the current defun to the Lisp process made by M-x run-lisp."
        !           153:   (interactive)
        !           154:   (error "Process lisp does not exist"))
        !           155: 
        !           156: (defvar lisp-interaction-mode-map ())
        !           157: (if lisp-interaction-mode-map
        !           158:     ()
        !           159:   (setq lisp-interaction-mode-map (make-sparse-keymap))
        !           160:   (lisp-mode-commands lisp-interaction-mode-map)
        !           161:   (define-key lisp-interaction-mode-map "\e\C-x" 'eval-defun)
        !           162:   (define-key lisp-interaction-mode-map "\n" 'eval-print-last-sexp))
        !           163: 
        !           164: (defun lisp-interaction-mode ()
        !           165:   "Major mode for typing and evaluating Lisp forms.
        !           166: Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression
        !           167: before point, and prints its value into the buffer, advancing point.
        !           168: 
        !           169: Commands:
        !           170: Delete converts tabs to spaces as it moves back.
        !           171: Paragraphs are separated only by blank lines.  Semicolons start comments.
        !           172: \\{lisp-interaction-mode-map}
        !           173: Entry to this mode calls the value of lisp-interaction-mode-hook
        !           174: if that value is non-nil."
        !           175:   (interactive)
        !           176:   (kill-all-local-variables)
        !           177:   (use-local-map lisp-interaction-mode-map)
        !           178:   (setq major-mode 'lisp-interaction-mode)
        !           179:   (setq mode-name "Lisp Interaction")
        !           180:   (lisp-mode-variables t)
        !           181:   (run-hooks 'lisp-interaction-mode-hook))
        !           182: 
        !           183: (defun eval-print-last-sexp (arg)
        !           184:   "Evaluate sexp before point; print value into current buffer."
        !           185:   (interactive "P")
        !           186:   (eval-region
        !           187:     (let ((stab (syntax-table)))
        !           188:       (unwind-protect
        !           189:          (save-excursion
        !           190:            (set-syntax-table emacs-lisp-mode-syntax-table)
        !           191:            (forward-sexp -1)
        !           192:            (point))
        !           193:        (set-syntax-table stab)))
        !           194:     (point)
        !           195:     (current-buffer)))
        !           196: 
        !           197: (defun eval-last-sexp (arg)
        !           198:   "Evaluate sexp before point; print value in minibuffer.
        !           199: With argument, print output into current buffer."
        !           200:   (interactive "P")
        !           201:   (eval-region
        !           202:     (let ((stab (syntax-table)))
        !           203:       (unwind-protect
        !           204:          (save-excursion
        !           205:            (set-syntax-table emacs-lisp-mode-syntax-table)
        !           206:            (forward-sexp -1)
        !           207:            (point))
        !           208:        (set-syntax-table stab)))
        !           209:     (point)
        !           210:     (if arg (current-buffer) t)))
        !           211: 
        !           212: (defun eval-defun (arg)
        !           213:   "Evaluate defun that point is in or before.
        !           214: Print value in minibuffer.
        !           215: With argument, insert value in current buffer after the defun."
        !           216:   (interactive "P")
        !           217:   (save-excursion
        !           218:     (end-of-defun)
        !           219:     (let ((end (point)))
        !           220:       (beginning-of-defun)
        !           221:       (eval-region (point) end
        !           222:                   (if arg (current-buffer) t)))))
        !           223: 
        !           224: (defun lisp-comment-indent ()
        !           225:   (if (looking-at ";;;")
        !           226:       (current-column)
        !           227:     (if (looking-at ";;")
        !           228:        (let ((tem (calculate-lisp-indent)))
        !           229:          (if (listp tem) (car tem) tem))
        !           230:       (skip-chars-backward " \t")
        !           231:       (max (if (bolp) 0 (1+ (current-column)))
        !           232:           comment-column))))
        !           233: 
        !           234: (defconst lisp-indent-offset nil "")
        !           235: (defconst lisp-indent-hook 'lisp-indent-hook "")
        !           236: 
        !           237: (defun lisp-indent-line (&optional whole-exp)
        !           238:   "Indent current line as Lisp code.
        !           239: With argument, indent any additional lines of the same expression
        !           240: rigidly along with this one."
        !           241:   (interactive "P")
        !           242:   (let ((indent (calculate-lisp-indent)) shift-amt beg end
        !           243:        (pos (- (point-max) (point))))
        !           244:     (beginning-of-line)
        !           245:     (setq beg (point))
        !           246:     (skip-chars-forward " \t")
        !           247:     (if (looking-at ";;;")
        !           248:        ;; Don't alter indentation of a ;;; comment line.
        !           249:        nil
        !           250:       (if (and (looking-at ";") (not (looking-at ";;")))
        !           251:          ;; Single-semicolon comment lines should be indented
        !           252:          ;; as comment lines, not as code.
        !           253:          (progn (indent-for-comment) (forward-char -1))
        !           254:        (if (listp indent) (setq indent (car indent)))
        !           255:        (setq shift-amt (- indent (current-column)))
        !           256:        (if (zerop shift-amt)
        !           257:            nil
        !           258:          (delete-region beg (point))
        !           259:          (indent-to indent)))
        !           260:       ;; If initial point was within line's indentation,
        !           261:       ;; position after the indentation.  Else stay at same point in text.
        !           262:       (if (> (- (point-max) pos) (point))
        !           263:          (goto-char (- (point-max) pos)))
        !           264:       ;; If desired, shift remaining lines of expression the same amount.
        !           265:       (and whole-exp (not (zerop shift-amt))
        !           266:           (save-excursion
        !           267:             (goto-char beg)
        !           268:             (forward-sexp 1)
        !           269:             (setq end (point))
        !           270:             (goto-char beg)
        !           271:             (forward-line 1)
        !           272:             (setq beg (point))
        !           273:             (> end beg))
        !           274:           (indent-code-rigidly beg end shift-amt)))))
        !           275: 
        !           276: (defun calculate-lisp-indent (&optional parse-start)
        !           277:   "Return appropriate indentation for current line as Lisp code.
        !           278: In usual case returns an integer: the column to indent to.
        !           279: Can instead return a list, whose car is the column to indent to.
        !           280: This means that following lines at the same level of indentation
        !           281: should not necessarily be indented the same way.
        !           282: The second element of the list is the buffer position
        !           283: of the start of the containing expression."
        !           284:   (save-excursion
        !           285:     (beginning-of-line)
        !           286:     (let ((indent-point (point))
        !           287:           state paren-depth
        !           288:           ;; setting this to a number inhibits calling hook
        !           289:           (desired-indent nil)
        !           290:           (retry t)
        !           291:           last-sexp containing-sexp)
        !           292:       (if parse-start
        !           293:           (goto-char parse-start)
        !           294:           (beginning-of-defun))
        !           295:       ;; Find outermost containing sexp
        !           296:       (while (< (point) indent-point)
        !           297:         (setq state (parse-partial-sexp (point) indent-point 0)))
        !           298:       ;; Find innermost containing sexp
        !           299:       (while (and retry
        !           300:                  state
        !           301:                   (> (setq paren-depth (elt state 0)) 0))
        !           302:         (setq retry nil)
        !           303:         (setq last-sexp (elt state 2))
        !           304:         (setq containing-sexp (elt state 1))
        !           305:         ;; Position following last unclosed open.
        !           306:         (goto-char (1+ containing-sexp))
        !           307:         ;; Is there a complete sexp since then?
        !           308:         (if (and last-sexp (> last-sexp (point)))
        !           309:             ;; Yes, but is there a containing sexp after that?
        !           310:             (let ((peek (parse-partial-sexp last-sexp indent-point 0)))
        !           311:               (if (setq retry (car (cdr peek))) (setq state peek)))))
        !           312:       (if retry
        !           313:           nil
        !           314:         ;; Innermost containing sexp found
        !           315:         (goto-char (1+ containing-sexp))
        !           316:         (if (not last-sexp)
        !           317:            ;; indent-point immediately follows open paren.
        !           318:            ;; Don't call hook.
        !           319:             (setq desired-indent (current-column))
        !           320:          ;; Find the start of first element of containing sexp.
        !           321:          (parse-partial-sexp (point) last-sexp 0 t)
        !           322:          (cond ((looking-at "\\s(")
        !           323:                 ;; First element of containing sexp is a list.
        !           324:                 ;; Indent under that list.
        !           325:                 )
        !           326:                ((> (save-excursion (forward-line 1) (point))
        !           327:                    last-sexp)
        !           328:                 ;; This is the first line to start within the containing sexp.
        !           329:                 ;; It's almost certainly a function call.
        !           330:                 (if (= (point) last-sexp)
        !           331:                     ;; Containing sexp has nothing before this line
        !           332:                     ;; except the first element.  Indent under that element.
        !           333:                     nil
        !           334:                   ;; Skip the first element, find start of second (the first
        !           335:                   ;; argument of the function call) and indent under.
        !           336:                   (progn (forward-sexp 1)
        !           337:                          (parse-partial-sexp (point) last-sexp 0 t)))
        !           338:                 (backward-prefix-chars))
        !           339:                (t
        !           340:                 ;; Indent beneath first sexp on same line as last-sexp.
        !           341:                 ;; Again, it's almost certainly a function call.
        !           342:                 (goto-char last-sexp)
        !           343:                 (beginning-of-line)
        !           344:                 (parse-partial-sexp (point) last-sexp 0 t)
        !           345:                 (backward-prefix-chars)))))
        !           346:       ;; Point is at the point to indent under unless we are inside a string.
        !           347:       ;; Call indentation hook except when overriden by lisp-indent-offset
        !           348:       ;; or if the desired indentation has already been computed.
        !           349:       (let ((normal-indent (current-column)))
        !           350:         (cond ((elt state 3)
        !           351:                ;; Inside a string, don't change indentation.
        !           352:                (goto-char indent-point)
        !           353:                (skip-chars-forward " \t")
        !           354:                (current-column))
        !           355:               ((and (integerp lisp-indent-offset) containing-sexp)
        !           356:                ;; Indent by constant offset
        !           357:                (goto-char containing-sexp)
        !           358:                (+ normal-indent lisp-indent-offset))
        !           359:               (desired-indent)
        !           360:               ((and (boundp 'lisp-indent-hook)
        !           361:                     lisp-indent-hook
        !           362:                     (not retry))
        !           363:                (or (funcall lisp-indent-hook indent-point state)
        !           364:                    normal-indent))
        !           365:               (t
        !           366:                normal-indent))))))
        !           367: 
        !           368: (defun lisp-indent-hook (indent-point state)
        !           369:   (let ((normal-indent (current-column)))
        !           370:     (goto-char (1+ (elt state 1)))
        !           371:     (parse-partial-sexp (point) last-sexp 0 t)
        !           372:     (if (and (elt state 2)
        !           373:              (not (looking-at "\\sw\\|\\s_")))
        !           374:         ;; car of form doesn't seem to be a a symbol
        !           375:         (progn
        !           376:           (if (not (> (save-excursion (forward-line 1) (point))
        !           377:                       last-sexp))
        !           378:               (progn (goto-char last-sexp)
        !           379:                      (beginning-of-line)
        !           380:                      (parse-partial-sexp (point) last-sexp 0 t)))
        !           381:           ;; Indent under the list or under the first sexp on the
        !           382:           ;; same line as last-sexp.  Note that first thing on that
        !           383:           ;; line has to be complete sexp since we are inside the
        !           384:           ;; innermost containing sexp.
        !           385:           (backward-prefix-chars)
        !           386:           (current-column))
        !           387:       (let ((function (buffer-substring (point)
        !           388:                                        (progn (forward-sexp 1) (point))))
        !           389:            method)
        !           390:        (setq method (get (intern-soft function) 'lisp-indent-hook))
        !           391:        (cond ((or (eq method 'defun)
        !           392:                   (and (null method)
        !           393:                        (> (length function) 3)
        !           394:                        (string-match "\\`def" function)))
        !           395:               (lisp-indent-defform state indent-point))
        !           396:              ((integerp method)
        !           397:               (lisp-indent-specform method state
        !           398:                                     indent-point normal-indent))
        !           399:              (method
        !           400:                (funcall method state indent-point)))))))
        !           401: 
        !           402: (defconst lisp-body-indent 2 "")
        !           403: 
        !           404: (defun lisp-indent-specform (count state indent-point normal-indent)
        !           405:   (let ((containing-form-start (elt state 1))
        !           406:         (i count)
        !           407:         body-indent containing-form-column)
        !           408:     ;; Move to the start of containing form, calculate indentation
        !           409:     ;; to use for non-distinguished forms (> count), and move past the
        !           410:     ;; function symbol.  lisp-indent-hook guarantees that there is at
        !           411:     ;; least one word or symbol character following open paren of containing
        !           412:     ;; form.
        !           413:     (goto-char containing-form-start)
        !           414:     (setq containing-form-column (current-column))
        !           415:     (setq body-indent (+ lisp-body-indent containing-form-column))
        !           416:     (forward-char 1)
        !           417:     (forward-sexp 1)
        !           418:     ;; Now find the start of the last form.
        !           419:     (parse-partial-sexp (point) indent-point 1 t)
        !           420:     (while (and (< (point) indent-point)
        !           421:                 (condition-case ()
        !           422:                     (progn
        !           423:                       (setq count (1- count))
        !           424:                       (forward-sexp 1)
        !           425:                       (parse-partial-sexp (point) indent-point 1 t))
        !           426:                   (error nil))))
        !           427:     ;; Point is sitting on first character of last (or count) sexp.
        !           428:     (if (> count 0)
        !           429:         ;; A distinguished form.  If it is the first or second form use double
        !           430:         ;; lisp-body-indent, else normal indent.  With lisp-body-indent bound
        !           431:         ;; to 2 (the default), this just happens to work the same with if as
        !           432:         ;; the older code, but it makes unwind-protect, condition-case,
        !           433:         ;; with-output-to-temp-buffer, et. al. much more tasteful.  The older,
        !           434:         ;; less hacked, behavior can be obtained by replacing below with
        !           435:         ;; (list normal-indent containing-form-start).
        !           436:         (if (<= (- i count) 1)
        !           437:             (list (+ containing-form-column (* 2 lisp-body-indent))
        !           438:                   containing-form-start)
        !           439:             (list normal-indent containing-form-start))
        !           440:       ;; A non-distinguished form.  Use body-indent if there are no
        !           441:       ;; distinguished forms and this is the first undistinguished form,
        !           442:       ;; or if this is the first undistinguished form and the preceding
        !           443:       ;; distinguished form has indentation at least as great as body-indent.
        !           444:       (if (or (and (= i 0) (= count 0))
        !           445:               (and (= count 0) (<= body-indent normal-indent)))
        !           446:           body-indent
        !           447:           normal-indent))))
        !           448: 
        !           449: (defun lisp-indent-defform (state indent-point)
        !           450:   (goto-char (car (cdr state)))
        !           451:   (forward-line 1)
        !           452:   (if (> (point) (car (cdr (cdr state))))
        !           453:       (progn
        !           454:        (goto-char (car (cdr state)))
        !           455:        (+ lisp-body-indent (current-column)))))
        !           456: 
        !           457: 
        !           458: ;; (put 'progn 'lisp-indent-hook 0), say, causes progn to be indented
        !           459: ;; like defun if the first form is placed on the next line, otherwise
        !           460: ;; it is indented like any other form (i.e. forms line up under first).
        !           461: 
        !           462: (put 'lambda 'lisp-indent-hook 'defun)
        !           463: (put 'progn 'lisp-indent-hook 0)
        !           464: (put 'prog1 'lisp-indent-hook 1)
        !           465: (put 'save-excursion 'lisp-indent-hook 0)
        !           466: (put 'save-window-excursion 'lisp-indent-hook 0)
        !           467: (put 'save-restriction 'lisp-indent-hook 0)
        !           468: (put 'let 'lisp-indent-hook 1)
        !           469: (put 'let* 'lisp-indent-hook 1)
        !           470: (put 'while 'lisp-indent-hook 1)
        !           471: (put 'if 'lisp-indent-hook 2)
        !           472: (put 'catch 'lisp-indent-hook 1)
        !           473: (put 'condition-case 'lisp-indent-hook 2)
        !           474: (put 'unwind-protect 'lisp-indent-hook 1)
        !           475: (put 'with-output-to-temp-buffer 'lisp-indent-hook 1)
        !           476: 
        !           477: (defun indent-sexp ()
        !           478:   "Indent each line of the list starting just after point."
        !           479:   (interactive)
        !           480:   (let ((indent-stack (list nil)) (next-depth 0) bol
        !           481:        outer-loop-done inner-loop-done state this-indent)
        !           482:     ;; Get error now if we don't have a complete sexp after point.
        !           483:     (save-excursion (forward-sexp 1))
        !           484:     (save-excursion
        !           485:       (setq outer-loop-done nil)
        !           486:       (while (not outer-loop-done)
        !           487:        (setq last-depth next-depth
        !           488:              innerloop-done nil)
        !           489:        ;; Parse this line so we can learn the state
        !           490:        ;; to indent the next line.
        !           491:        ;; This inner loop goes through only once
        !           492:        ;; unless a line ends inside a string.
        !           493:        (while (and (not innerloop-done)
        !           494:                    (not (setq outer-loop-done (eobp))))
        !           495:          (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
        !           496:                                          nil nil state))
        !           497:          (setq next-depth (car state))
        !           498:          ;; If the line contains a comment other than the sort
        !           499:          ;; that is indented like code,
        !           500:          ;; indent it now with indent-for-comment.
        !           501:          ;; Comments indented like code are right already.
        !           502:          ;; In any case clear the in-comment flag in the state
        !           503:          ;; because parse-partial-sexp never sees the newlines.
        !           504:          (if (car (nthcdr 4 state))
        !           505:              (progn (indent-for-comment)
        !           506:                     (end-of-line)
        !           507:                     (setcar (nthcdr 4 state) nil)))
        !           508:          ;; If this line ends inside a string,
        !           509:          ;; go straight to next line, remaining within the inner loop,
        !           510:          ;; and turn off the \-flag.
        !           511:          (if (car (nthcdr 3 state))
        !           512:              (progn
        !           513:                (forward-line 1)
        !           514:                (setcar (nthcdr 5 state) nil))
        !           515:            (setq innerloop-done t)))
        !           516:        (if (setq outer-loop-done (<= next-depth 0))
        !           517:            nil
        !           518:          (while (> last-depth next-depth)
        !           519:            (setq indent-stack (cdr indent-stack)
        !           520:                  last-depth (1- last-depth)))
        !           521:          (while (< last-depth next-depth)
        !           522:            (setq indent-stack (cons nil indent-stack)
        !           523:                  last-depth (1+ last-depth)))
        !           524:          ;; Now go to the next line and indent it according
        !           525:          ;; to what we learned from parsing the previous one.
        !           526:          (forward-line 1)
        !           527:          (setq bol (point))
        !           528:          (skip-chars-forward " \t")
        !           529:          ;; But not if the line is blank, or just a comment
        !           530:          ;; (except for double-semi comments; indent them as usual).
        !           531:          (if (or (eobp) (looking-at "[;\n]"))
        !           532:              nil
        !           533:            (if (and (car indent-stack)
        !           534:                     (>= (car indent-stack) 0))
        !           535:                (setq this-indent (car indent-stack))
        !           536:              (let ((val (calculate-lisp-indent
        !           537:                          (if (car indent-stack) (- (car indent-stack))))))
        !           538:                (if (integerp val)
        !           539:                    (setcar indent-stack
        !           540:                            (setq this-indent val))
        !           541:                  (setcar indent-stack (- (car (cdr val))))
        !           542:                  (setq this-indent (car val)))))
        !           543:            (if (/= (current-column) this-indent)
        !           544:                (progn (delete-region bol (point))
        !           545:                       (indent-to this-indent)))))))))
        !           546: 
        !           547: (defun indent-code-rigidly (start end arg &optional nochange-regexp)
        !           548:   "Indent all lines of code, starting in the region, sideways by ARG columns.
        !           549: Does not affect lines starting inside comments or strings,
        !           550: assuming that the start of the region is not inside them.
        !           551: Called from a program, takes args START, END, COLUMNS and NOCHANGE-REGEXP.
        !           552: The last is a regexp which, if matched at the beginning of a line,
        !           553: means don't indent that line."
        !           554:   (interactive "r\np")
        !           555:   (let (state)
        !           556:     (save-excursion
        !           557:       (goto-char end)
        !           558:       (setq end (point-marker))
        !           559:       (goto-char start)
        !           560:       (or (bolp)
        !           561:          (setq state (parse-partial-sexp (point)
        !           562:                                          (progn
        !           563:                                            (forward-line 1) (point))
        !           564:                                          nil nil state)))
        !           565:       (while (< (point) end)
        !           566:        (or (car (nthcdr 3 state))
        !           567:            (and nochange-regexp
        !           568:                 (looking-at nochange-regexp))
        !           569:            ;; If line does not start in string, indent it
        !           570:            (let ((indent (current-indentation)))
        !           571:              (delete-region (point) (progn (skip-chars-forward " \t") (point)))
        !           572:              (or (eolp)
        !           573:                  (indent-to (max 0 (+ indent arg)) 0))))
        !           574:        (setq state (parse-partial-sexp (point)
        !           575:                                        (progn
        !           576:                                          (forward-line 1) (point))
        !           577:                                        nil nil state))))))
        !           578: 

unix.superglobalmegacorp.com

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