Annotation of 43BSDReno/contrib/emacs-18.55/lisp/lisp-mode.el, revision 1.1.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.