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

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

unix.superglobalmegacorp.com

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