Annotation of 43BSDReno/contrib/emacs-18.55/lisp/fortran.el, revision 1.1.1.1

1.1       root        1: ;;; Fortran mode for GNU Emacs  (beta test version 1.21, Oct. 1, 1985)
                      2: ;;; Copyright (c) 1986 Free Software Foundation, Inc.
                      3: ;;; Written by Michael D. Prange (mit-eddie!mit-erl!prange).
                      4: 
                      5: ;;; This file is not part of the GNU Emacs distribution (yet).
                      6: 
                      7: ;; This file is distributed in the hope that it will be useful,
                      8: ;; but WITHOUT ANY WARRANTY.  No author or distributor
                      9: ;; accepts responsibility to anyone for the consequences of using it
                     10: ;; or for whether it serves any particular purpose or works at all,
                     11: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
                     12: ;; License for full details.
                     13: 
                     14: ;; Everyone is granted permission to copy, modify and redistribute
                     15: ;; this file, but only under the conditions described in the
                     16: ;; GNU Emacs General Public License.   A copy of this license is
                     17: ;; supposed to have been given to you along with GNU Emacs so you
                     18: ;; can know your rights and responsibilities.  It should be in a
                     19: ;; file named COPYING.  Among other things, the copyright notice
                     20: ;; and this notice must be preserved on all copies.
                     21: 
                     22: ;;; Author acknowledges help from Stephen Gildea <mit-erl!gildea>
                     23: 
                     24: ;;; Bugs to mit-erl!bug-fortran-mode.
                     25: 
                     26: (defvar fortran-do-indent 3
                     27:   "*Extra indentation applied to `do' blocks.")
                     28: 
                     29: (defvar fortran-if-indent 3
                     30:   "*Extra indentation applied to `if' blocks.")
                     31: 
                     32: (defvar fortran-continuation-indent 5
                     33:   "*Extra indentation applied to `continuation' lines.")
                     34: 
                     35: (defvar fortran-comment-indent-style 'fixed
                     36:   "*nil forces comment lines not to be touched,
                     37: 'fixed produces fixed comment indentation to comment-column,
                     38: and 'relative indents to current fortran indentation plus comment-column.")
                     39: 
                     40: (defvar fortran-comment-line-column 6
                     41:   "*Indentation for text in comment lines.")
                     42: 
                     43: (defvar comment-line-start nil
                     44:   "*Delimiter inserted to start new full-line comment.")
                     45: 
                     46: (defvar comment-line-start-skip nil
                     47:   "*Regexp to match the start of a full-line comment.")
                     48: 
                     49: (defvar fortran-minimum-statement-indent 6
                     50:   "*Minimum indentation for fortran statements.")
                     51: 
                     52: ;; Note that this is documented in the v18 manuals as being a string
                     53: ;; of length one rather than a single character.
                     54: ;; The code in this file accepts either format for compatibility.
                     55: (defvar fortran-comment-indent-char ? 
                     56:   "*Character to be inserted for Fortran comment indentation.
                     57: Normally a space.")
                     58: 
                     59: (defvar fortran-line-number-indent 1
                     60:   "*Maximum indentation for Fortran line numbers.
                     61: 5 means right-justify them within their five-column field.")
                     62: 
                     63: (defvar fortran-check-all-num-for-matching-do nil
                     64:   "*Non-nil causes all numbered lines to be treated as possible do-loop ends.")
                     65: 
                     66: (defvar fortran-continuation-char ?$
                     67:   "*Character which is inserted in column 5 by \\[fortran-split-line]
                     68: to begin a continuation line.  Normally $.")
                     69: 
                     70: (defvar fortran-comment-region "c$$$"
                     71:   "*String inserted by \\[fortran-comment-region] at start of each line in region.")
                     72: 
                     73: (defvar fortran-electric-line-number t
                     74:   "*Non-nil causes line number digits to be moved to the correct column as typed.")
                     75: 
                     76: (defvar fortran-startup-message t
                     77:   "*Non-nil displays a startup message when fortran-mode is first called.")
                     78: 
                     79: (defvar fortran-column-ruler
                     80:   (concat "0   4 6  10        20        30        40        50        60        70\n"
                     81:          "[   ]|{   |    |    |    |    |    |    |    |    |    |    |    |    |}\n")
                     82:   "*String displayed above current line by \\[fortran-column-ruler].")
                     83: 
                     84: (defconst fortran-mode-version "1.21")
                     85: 
                     86: (defvar fortran-mode-syntax-table nil
                     87:   "Syntax table in use in fortran-mode buffers.")
                     88: 
                     89: (if fortran-mode-syntax-table
                     90:     ()
                     91:   (setq fortran-mode-syntax-table (make-syntax-table))
                     92:   (modify-syntax-entry ?\; "w" fortran-mode-syntax-table)
                     93:   (modify-syntax-entry ?+ "." fortran-mode-syntax-table)
                     94:   (modify-syntax-entry ?- "." fortran-mode-syntax-table)
                     95:   (modify-syntax-entry ?* "." fortran-mode-syntax-table)
                     96:   (modify-syntax-entry ?/ "." fortran-mode-syntax-table)
                     97:   (modify-syntax-entry ?\' "\"" fortran-mode-syntax-table)
                     98:   (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table)
                     99:   (modify-syntax-entry ?\\ "/" fortran-mode-syntax-table)
                    100:   (modify-syntax-entry ?. "w" fortran-mode-syntax-table)
                    101:   (modify-syntax-entry ?\n ">" fortran-mode-syntax-table))
                    102: 
                    103: (defvar fortran-mode-map () 
                    104:   "Keymap used in fortran mode.")
                    105: 
                    106: (if fortran-mode-map
                    107:     ()
                    108:   (setq fortran-mode-map (make-sparse-keymap))
                    109:   (define-key fortran-mode-map ";" 'fortran-abbrev-start)
                    110:   (define-key fortran-mode-map "\C-c;" 'fortran-comment-region)
                    111:   (define-key fortran-mode-map "\e\C-a" 'beginning-of-fortran-subprogram)
                    112:   (define-key fortran-mode-map "\e\C-e" 'end-of-fortran-subprogram)
                    113:   (define-key fortran-mode-map "\e;" 'fortran-indent-comment)
                    114:   (define-key fortran-mode-map "\e\C-h" 'mark-fortran-subprogram)
                    115:   (define-key fortran-mode-map "\e\n" 'fortran-split-line)
                    116:   (define-key fortran-mode-map "\e\C-q" 'fortran-indent-subprogram)
                    117:   (define-key fortran-mode-map "\C-c\C-w" 'fortran-window-create)
                    118:   (define-key fortran-mode-map "\C-c\C-r" 'fortran-column-ruler)
                    119:   (define-key fortran-mode-map "\C-c\C-p" 'fortran-previous-statement)
                    120:   (define-key fortran-mode-map "\C-c\C-n" 'fortran-next-statement)
                    121:   (define-key fortran-mode-map "\t" 'fortran-indent-line)
                    122:   (define-key fortran-mode-map "0" 'fortran-electric-line-number)
                    123:   (define-key fortran-mode-map "1" 'fortran-electric-line-number)
                    124:   (define-key fortran-mode-map "2" 'fortran-electric-line-number)
                    125:   (define-key fortran-mode-map "3" 'fortran-electric-line-number)
                    126:   (define-key fortran-mode-map "4" 'fortran-electric-line-number)
                    127:   (define-key fortran-mode-map "5" 'fortran-electric-line-number)
                    128:   (define-key fortran-mode-map "6" 'fortran-electric-line-number)
                    129:   (define-key fortran-mode-map "7" 'fortran-electric-line-number)
                    130:   (define-key fortran-mode-map "8" 'fortran-electric-line-number)
                    131:   (define-key fortran-mode-map "9" 'fortran-electric-line-number))
                    132: 
                    133: (defvar fortran-mode-abbrev-table nil)
                    134: (if fortran-mode-abbrev-table
                    135:     ()
                    136:   (define-abbrev-table 'fortran-mode-abbrev-table ())
                    137:   (let ((abbrevs-changed nil))
                    138:     (define-abbrev fortran-mode-abbrev-table  ";b"   "byte" nil)
                    139:     (define-abbrev fortran-mode-abbrev-table  ";ch"  "character" nil)
                    140:     (define-abbrev fortran-mode-abbrev-table  ";cl"  "close" nil)
                    141:     (define-abbrev fortran-mode-abbrev-table  ";c"   "continue" nil)
                    142:     (define-abbrev fortran-mode-abbrev-table  ";cm"  "common" nil)
                    143:     (define-abbrev fortran-mode-abbrev-table  ";cx"  "complex" nil)
                    144:     (define-abbrev fortran-mode-abbrev-table  ";di"  "dimension" nil)
                    145:     (define-abbrev fortran-mode-abbrev-table  ";do"  "double" nil)
                    146:     (define-abbrev fortran-mode-abbrev-table  ";dc"  "double complex" nil)
                    147:     (define-abbrev fortran-mode-abbrev-table  ";dp"  "double precision" nil)
                    148:     (define-abbrev fortran-mode-abbrev-table  ";dw"  "do while" nil)
                    149:     (define-abbrev fortran-mode-abbrev-table  ";e"   "else" nil)
                    150:     (define-abbrev fortran-mode-abbrev-table  ";ed"  "enddo" nil)
                    151:     (define-abbrev fortran-mode-abbrev-table  ";el"  "elseif" nil)
                    152:     (define-abbrev fortran-mode-abbrev-table  ";en"  "endif" nil)
                    153:     (define-abbrev fortran-mode-abbrev-table  ";eq"  "equivalence" nil)
                    154:     (define-abbrev fortran-mode-abbrev-table  ";ex"  "external" nil)
                    155:     (define-abbrev fortran-mode-abbrev-table  ";ey"  "entry" nil)
                    156:     (define-abbrev fortran-mode-abbrev-table  ";f"   "format" nil)
                    157:     (define-abbrev fortran-mode-abbrev-table  ";fu"  "function" nil)
                    158:     (define-abbrev fortran-mode-abbrev-table  ";g"   "goto" nil)
                    159:     (define-abbrev fortran-mode-abbrev-table  ";im"  "implicit" nil)
                    160:     (define-abbrev fortran-mode-abbrev-table  ";ib"  "implicit byte" nil)
                    161:     (define-abbrev fortran-mode-abbrev-table  ";ic"  "implicit complex" nil)
                    162:     (define-abbrev fortran-mode-abbrev-table  ";ich" "implicit character" nil)
                    163:     (define-abbrev fortran-mode-abbrev-table  ";ii"  "implicit integer" nil)
                    164:     (define-abbrev fortran-mode-abbrev-table  ";il"  "implicit logical" nil)
                    165:     (define-abbrev fortran-mode-abbrev-table  ";ir"  "implicit real" nil)
                    166:     (define-abbrev fortran-mode-abbrev-table  ";inc" "include" nil)
                    167:     (define-abbrev fortran-mode-abbrev-table  ";in"  "integer" nil)
                    168:     (define-abbrev fortran-mode-abbrev-table  ";intr" "intrinsic" nil)
                    169:     (define-abbrev fortran-mode-abbrev-table  ";l"   "logical" nil)
                    170:     (define-abbrev fortran-mode-abbrev-table  ";op"  "open" nil)
                    171:     (define-abbrev fortran-mode-abbrev-table  ";pa"  "parameter" nil)
                    172:     (define-abbrev fortran-mode-abbrev-table  ";pr"  "program" nil)
                    173:     (define-abbrev fortran-mode-abbrev-table  ";p"   "print" nil)
                    174:     (define-abbrev fortran-mode-abbrev-table  ";re"  "real" nil)
                    175:     (define-abbrev fortran-mode-abbrev-table  ";r"   "read" nil)
                    176:     (define-abbrev fortran-mode-abbrev-table  ";rt"  "return" nil)
                    177:     (define-abbrev fortran-mode-abbrev-table  ";rw"  "rewind" nil)
                    178:     (define-abbrev fortran-mode-abbrev-table  ";s"   "stop" nil)
                    179:     (define-abbrev fortran-mode-abbrev-table  ";su"  "subroutine" nil)
                    180:     (define-abbrev fortran-mode-abbrev-table  ";ty"  "type" nil)
                    181:     (define-abbrev fortran-mode-abbrev-table  ";w"   "write" nil)))
                    182: 
                    183: (defun fortran-mode ()
                    184:   "Major mode for editing fortran code.
                    185: Tab indents the current fortran line correctly. 
                    186: `do' statements must not share a common `continue'.
                    187: 
                    188: Type `;?' or `;\\[help-command]' to display a list of built-in abbrevs for Fortran keywords.
                    189: 
                    190: Variables controlling indentation style and extra features:
                    191: 
                    192:  comment-start
                    193:     Normally nil in Fortran mode.  If you want to use comments
                    194:     starting with `!', set this to the string \"!\".
                    195:  fortran-do-indent
                    196:     Extra indentation within do blocks.  (default 3)
                    197:  fortran-if-indent
                    198:     Extra indentation within if blocks.  (default 3)
                    199:  fortran-continuation-indent
                    200:     Extra indentation appled to continuation statements.  (default 5)
                    201:  fortran-comment-line-column
                    202:     Amount of indentation for text within full-line comments. (default 6)
                    203:  fortran-comment-indent-style
                    204:     nil    means don't change indentation of text in full-line comments,
                    205:     fixed  means indent that text at column fortran-comment-line-column
                    206:     relative  means indent at fortran-comment-line-column beyond the
                    207:              indentation for a line of code.
                    208:     Default value is fixed.
                    209:  fortran-comment-indent-char
                    210:     Character to be inserted instead of space for full-line comment
                    211:     indentation.  (default is a space)
                    212:  fortran-minimum-statement-indent
                    213:     Minimum indentation for fortran statements. (default 6)
                    214:  fortran-line-number-indent
                    215:     Maximum indentation for line numbers.  A line number will get
                    216:     less than this much indentation if necessary to avoid reaching
                    217:     column 5.  (default 1)
                    218:  fortran-check-all-num-for-matching-do
                    219:     Non-nil causes all numbered lines to be treated as possible 'continue'
                    220:     statements.  (default nil)
                    221:  fortran-continuation-char
                    222:     character to be inserted in column 5 of a continuation line.
                    223:     (default $)
                    224:  fortran-comment-region
                    225:     String inserted by \\[fortran-comment-region] at start of each line in 
                    226:     region.  (default \"c$$$\")
                    227:  fortran-electric-line-number
                    228:     Non-nil causes line number digits to be moved to the correct column 
                    229:     as typed.  (default t)
                    230:  fortran-startup-message
                    231:     Set to nil to inhibit message first time fortran-mode is used.
                    232: 
                    233: Turning on Fortran mode calls the value of the variable fortran-mode-hook 
                    234: with no args, if that value is non-nil.
                    235: \\{fortran-mode-map}"
                    236:   (interactive)
                    237:   (kill-all-local-variables)
                    238:   (if fortran-startup-message
                    239:       (message "Emacs Fortran mode version %s.  Bugs to mit-erl!bug-fortran-mode" fortran-mode-version))
                    240:   (setq fortran-startup-message nil)
                    241:   (setq local-abbrev-table fortran-mode-abbrev-table)
                    242:   (set-syntax-table fortran-mode-syntax-table)
                    243:   (make-local-variable 'indent-line-function)
                    244:   (setq indent-line-function 'fortran-indent-line)
                    245:   (make-local-variable 'comment-indent-hook)
                    246:   (setq comment-indent-hook 'fortran-comment-hook)
                    247:   (make-local-variable 'comment-line-start-skip)
                    248:   (setq comment-line-start-skip "^[Cc*][^ \t\n]*[ \t]*") ;[^ \t\n]* handles comment strings such as c$$$
                    249:   (make-local-variable 'comment-line-start)
                    250:   (setq comment-line-start "c")
                    251:   (make-local-variable 'comment-start-skip)
                    252:   (setq comment-start-skip "![ \t]*")
                    253:   (make-local-variable 'comment-start)
                    254:   (setq comment-start nil)
                    255:   (make-local-variable 'require-final-newline)
                    256:   (setq require-final-newline t)
                    257:   (make-local-variable 'abbrev-all-caps)
                    258:   (setq abbrev-all-caps t)
                    259:   (make-local-variable 'indent-tabs-mode)
                    260:   (setq indent-tabs-mode nil)
                    261:   (use-local-map fortran-mode-map)
                    262:   (setq mode-name "Fortran")
                    263:   (setq major-mode 'fortran-mode)
                    264:   (run-hooks 'fortran-mode-hook))
                    265: 
                    266: (defun fortran-comment-hook ()
                    267:   (save-excursion
                    268:     (skip-chars-backward " \t")
                    269:     (max (+ 1 (current-column))
                    270:         comment-column)))
                    271: 
                    272: (defun fortran-indent-comment ()
                    273:   "Align or create comment on current line.
                    274: Existing comments of all types are recognized and aligned.
                    275: If the line has no comment, a side-by-side comment is inserted and aligned
                    276: if the value of  comment-start  is not nil.
                    277: Otherwise, a separate-line comment is inserted, on this line
                    278: or on a new line inserted before this line if this line is not blank."
                    279:   (interactive)
                    280:   (beginning-of-line)
                    281:   ;; Recognize existing comments of either kind.
                    282:   (cond ((looking-at comment-line-start-skip)
                    283:         (fortran-indent-line))
                    284:        ((re-search-forward comment-start-skip
                    285:                            (save-excursion (end-of-line) (point)) t)
                    286:         (indent-for-comment))
                    287:        ;; No existing comment.
                    288:        ;; If side-by-side comments are defined, insert one,
                    289:        ;; unless line is now blank.
                    290:        ((and comment-start (not (looking-at "^[ \t]*$")))
                    291:         (end-of-line)
                    292:         (delete-horizontal-space)
                    293:         (indent-to (fortran-comment-hook))
                    294:         (insert comment-start))
                    295:        ;; Else insert separate-line comment, making a new line if nec.
                    296:        (t
                    297:         (if (looking-at "^[ \t]*$")
                    298:             (delete-horizontal-space)
                    299:           (beginning-of-line)
                    300:           (insert "\n")
                    301:           (forward-char -1))
                    302:         (insert comment-line-start)
                    303:         (insert-char (if (stringp fortran-comment-indent-char)
                    304:                          (aref fortran-comment-indent-char 0)
                    305:                          fortran-comment-indent-char)
                    306:                      (- (calculate-fortran-indent) (current-column))))))
                    307: 
                    308: (defun fortran-comment-region (beg-region end-region arg)
                    309:   "Comments every line in the region.
                    310: Puts fortran-comment-region at the beginning of every line in the region. 
                    311: BEG-REGION and END-REGION are args which specify the region boundaries. 
                    312: With non-nil ARG, uncomments the region."
                    313:   (interactive "*r\nP")
                    314:   (let ((end-region-mark (make-marker)) (save-point (point-marker)))
                    315:     (set-marker end-region-mark end-region)
                    316:     (goto-char beg-region)
                    317:     (beginning-of-line)
                    318:     (if (not arg)                      ;comment the region
                    319:        (progn (insert fortran-comment-region)
                    320:               (while (and  (= (forward-line 1) 0)
                    321:                            (< (point) end-region-mark))
                    322:                 (insert fortran-comment-region)))
                    323:       (let ((com (regexp-quote fortran-comment-region))) ;uncomment the region
                    324:        (if (looking-at com)
                    325:            (delete-region (point) (match-end 0)))
                    326:        (while (and  (= (forward-line 1) 0)
                    327:                     (< (point) end-region-mark))
                    328:          (if (looking-at com)
                    329:              (delete-region (point) (match-end 0))))))
                    330:     (goto-char save-point)
                    331:     (set-marker end-region-mark nil)
                    332:     (set-marker save-point nil)))
                    333: 
                    334: (defun fortran-abbrev-start ()
                    335:   "Typing \";\\[help-command]\" or \";?\" lists all the fortran abbrevs. 
                    336: Any other key combination is executed normally." ;\\[help-command] is just a way to print the value of the variable help-char.
                    337:   (interactive)
                    338:   (let (c)
                    339:     (insert last-command-char)
                    340:     (if (or (= (setq c (read-char)) ??)        ;insert char if not equal to `?'
                    341:            (= c help-char))
                    342:        (fortran-abbrev-help)
                    343:       (setq unread-command-char c))))
                    344: 
                    345: (defun fortran-abbrev-help ()
                    346:   "List the currently defined abbrevs in Fortran mode."
                    347:   (interactive)
                    348:   (message "Listing abbrev table...")
                    349:   (require 'abbrevlist)
                    350:   (list-one-abbrev-table fortran-mode-abbrev-table "*Help*")
                    351:   (message "Listing abbrev table...done"))
                    352: 
                    353: (defun fortran-column-ruler ()
                    354:   "Inserts a column ruler momentarily above current line, till next keystroke.
                    355: The ruler is defined by the value of fortran-column-ruler.
                    356: The key typed is executed unless it is SPC."
                    357:   (interactive)
                    358:   (momentary-string-display 
                    359:    fortran-column-ruler (save-excursion (beginning-of-line) (point))
                    360:    nil "Type SPC or any command to erase ruler."))
                    361: 
                    362: (defun fortran-window-create ()
                    363:   "Makes the window 72 columns wide."
                    364:   (interactive)
                    365:   (let ((window-min-width 2))
                    366:     (split-window-horizontally 73))
                    367:   (other-window 1)
                    368:   (switch-to-buffer " fortran-window-extra" t)
                    369:   (select-window (previous-window)))
                    370: 
                    371: (defun fortran-split-line ()
                    372:   "Break line at point and insert continuation marker and alignment."
                    373:   (interactive)
                    374:   (delete-horizontal-space)
                    375:   (if (save-excursion (beginning-of-line) (looking-at comment-line-start-skip))
                    376:       (insert "\n" comment-line-start " ")
                    377:     (insert "\n " fortran-continuation-char))
                    378:   (fortran-indent-line))
                    379: 
                    380: (defun delete-horizontal-regexp (chars)
                    381:   "Delete all characters in CHARS around point.
                    382: CHARS is like the inside of a [...] in a regular expression
                    383: except that ] is never special and \ quotes ^, - or \."
                    384:   (interactive "*s")
                    385:   (skip-chars-backward chars)
                    386:   (delete-region (point) (progn (skip-chars-forward chars) (point))))
                    387: 
                    388: (defun fortran-electric-line-number (arg)
                    389:   "Self insert, but if part of a Fortran line number indent it automatically.
                    390: Auto-indent does not happen if a numeric arg is used."
                    391:   (interactive "P")
                    392:   (if (or arg (not fortran-electric-line-number))
                    393:       (self-insert-command arg)
                    394:     (if (or (save-excursion (re-search-backward "[^ \t0-9]"
                    395:                                                (save-excursion
                    396:                                                  (beginning-of-line)
                    397:                                                  (point))
                    398:                                                t)) ;not a line number
                    399:            (looking-at "[0-9]"))               ;within a line number
                    400:        (insert last-command-char)
                    401:       (skip-chars-backward " \t")
                    402:       (insert last-command-char)
                    403:       (fortran-indent-line))))
                    404: 
                    405: (defun beginning-of-fortran-subprogram ()
                    406:   "Moves point to the beginning of the current fortran subprogram."
                    407:   (interactive)
                    408:   (let ((case-fold-search t))
                    409:     (beginning-of-line -1)
                    410:     (re-search-backward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move)
                    411:     (if (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")
                    412:        (forward-line 1))))
                    413: 
                    414: (defun end-of-fortran-subprogram ()
                    415:   "Moves point to the end of the current fortran subprogram."
                    416:   (interactive)
                    417:   (let ((case-fold-search t))
                    418:     (beginning-of-line 2)
                    419:     (re-search-forward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move)
                    420:     (goto-char (match-beginning 0))
                    421:     (forward-line 1)))
                    422: 
                    423: (defun mark-fortran-subprogram ()
                    424:   "Put mark at end of fortran subprogram, point at beginning. 
                    425: The marks are pushed."
                    426:   (interactive)
                    427:   (end-of-fortran-subprogram)
                    428:   (push-mark (point))
                    429:   (beginning-of-fortran-subprogram))
                    430:   
                    431: (defun fortran-previous-statement ()
                    432:   "Moves point to beginning of the previous fortran statement.
                    433: Returns 'first-statement if that statement is the first
                    434: non-comment Fortran statement in the file, and nil otherwise."
                    435:   (interactive)
                    436:   (let (not-first-statement continue-test)
                    437:     (beginning-of-line)
                    438:     (setq continue-test
                    439:          (or (looking-at
                    440:                (concat "[ \t]*" (regexp-quote (char-to-string
                    441:                                                 fortran-continuation-char))))
                    442:              (looking-at "     [^ 0\n]")))
                    443:     (while (and (setq not-first-statement (= (forward-line -1) 0))
                    444:                (or (looking-at comment-line-start-skip)
                    445:                    (looking-at "[ \t]*$")
                    446:                    (looking-at "     [^ 0\n]")
                    447:                    (looking-at (concat "[ \t]*"  comment-start-skip)))))
                    448:     (cond ((and continue-test
                    449:                (not not-first-statement))
                    450:           (message "Incomplete continuation statement."))
                    451:          (continue-test        
                    452:           (fortran-previous-statement))
                    453:          ((not not-first-statement)
                    454:           'first-statement))))
                    455: 
                    456: (defun fortran-next-statement ()
                    457:   "Moves point to beginning of the next fortran statement.
                    458:  Returns 'last-statement if that statement is the last
                    459:  non-comment Fortran statement in the file, and nil otherwise."
                    460:   (interactive)
                    461:   (let (not-last-statement)
                    462:     (beginning-of-line)
                    463:     (while (and (setq not-last-statement (= (forward-line 1) 0))
                    464:                (or (looking-at comment-line-start-skip)
                    465:                    (looking-at "[ \t]*$")
                    466:                    (looking-at "     [^ 0\n]")
                    467:                    (looking-at (concat "[ \t]*"  comment-start-skip)))))
                    468:     (if (not not-last-statement)
                    469:        'last-statement)))
                    470: 
                    471: (defun fortran-indent-line ()
                    472:   "Indents current fortran line based on its contents and on previous lines."
                    473:   (interactive)
                    474:   (let ((cfi (calculate-fortran-indent)))
                    475:     (save-excursion
                    476:       (beginning-of-line)
                    477:       (if (or (not (= cfi (fortran-current-line-indentation)))
                    478:              (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t)
                    479:                   (not (fortran-line-number-indented-correctly-p))))
                    480:          (fortran-indent-to-column cfi)
                    481:        (beginning-of-line)
                    482:        (if (re-search-forward comment-start-skip
                    483:                               (save-excursion (end-of-line) (point)) 'move)
                    484:            (fortran-indent-comment))))
                    485:     ;; Never leave point in left margin.
                    486:     (if (< (current-column) cfi)
                    487:        (move-to-column cfi))))
                    488: 
                    489: (defun fortran-indent-subprogram ()
                    490:   "Properly indents the Fortran subprogram which contains point."
                    491:   (interactive)
                    492:   (save-excursion
                    493:     (mark-fortran-subprogram)
                    494:     (message "Indenting subprogram...")
                    495:     (indent-region (point) (mark) nil))
                    496:   (message "Indenting subprogram...done."))
                    497: 
                    498: (defun calculate-fortran-indent ()
                    499:   "Calculates the fortran indent column based on previous lines."
                    500:   (let (icol first-statement (case-fold-search t))
                    501:     (save-excursion
                    502:       (setq first-statement (fortran-previous-statement))
                    503:       (if first-statement
                    504:          (setq icol fortran-minimum-statement-indent)
                    505:        (progn
                    506:          (if (= (point) (point-min))
                    507:              (setq icol fortran-minimum-statement-indent)
                    508:            (setq icol (fortran-current-line-indentation)))
                    509:          (skip-chars-forward " \t0-9")
                    510:          (cond ((looking-at "if[ \t]*(")
                    511:                 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
                    512:                         (let (then-test)       ;multi-line if-then
                    513:                           (while (and (= (forward-line 1) 0) ;search forward for then
                    514:                                       (looking-at "     [^ 0]")
                    515:                                       (not (setq then-test (looking-at ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
                    516:                           then-test))
                    517:                     (setq icol (+ icol fortran-if-indent))))
                    518:                ((looking-at "\\(else\\|elseif\\)\\b")
                    519:                 (setq icol (+ icol fortran-if-indent)))
                    520:                ((looking-at "do\\b")
                    521:                 (setq icol (+ icol fortran-do-indent)))))))
                    522:     (save-excursion
                    523:       (beginning-of-line)
                    524:       (cond ((looking-at "[ \t]*$"))
                    525:            ((looking-at comment-line-start-skip)
                    526:             (cond ((eq fortran-comment-indent-style 'relative)
                    527:                    (setq icol (+ icol fortran-comment-line-column)))
                    528:                   ((eq fortran-comment-indent-style 'fixed)
                    529:                    (setq icol fortran-comment-line-column))))
                    530:            ((or (looking-at (concat "[ \t]*"
                    531:                                     (regexp-quote (char-to-string fortran-continuation-char))))
                    532:                 (looking-at "     [^ 0\n]"))
                    533:             (setq icol (+ icol fortran-continuation-indent)))
                    534:            (first-statement)
                    535:            ((and fortran-check-all-num-for-matching-do
                    536:                  (looking-at "[ \t]*[0-9]+")
                    537:                  (fortran-check-for-matching-do))
                    538:             (setq icol (- icol fortran-do-indent)))
                    539:            (t
                    540:             (skip-chars-forward " \t0-9")
                    541:             (cond ((looking-at "end[ \t]*if\\b")
                    542:                    (setq icol (- icol fortran-if-indent)))
                    543:                   ((looking-at "\\(else\\|elseif\\)\\b")
                    544:                    (setq icol (- icol fortran-if-indent)))
                    545:                   ((and (looking-at "continue\\b")
                    546:                         (fortran-check-for-matching-do))
                    547:                    (setq icol (- icol fortran-do-indent)))
                    548:                   ((looking-at "end[ \t]*do\\b")
                    549:                    (setq icol (- icol fortran-do-indent)))
                    550:                   ((and (looking-at "end\\b[ \t]*[^ \t=(a-z]")
                    551:                         (not (= icol fortran-minimum-statement-indent)))
                    552:                    (message "Warning: `end' not in column %d.  Probably an unclosed block." fortran-minimum-statement-indent))))))
                    553:     (max fortran-minimum-statement-indent icol)))
                    554: 
                    555: (defun fortran-current-line-indentation ()
                    556:   "Indentation of current line, ignoring Fortran line number or continuation.
                    557: This is the column position of the first non-whitespace character
                    558: aside from the line number and/or column 5 line-continuation character.
                    559: For comment lines, returns indentation of the first
                    560: non-indentation text within the comment."
                    561:   (save-excursion
                    562:     (beginning-of-line)
                    563:     (cond ((looking-at comment-line-start-skip)
                    564:           (goto-char (match-end 0))
                    565:           (skip-chars-forward
                    566:             (if (stringp fortran-comment-indent-char)
                    567:                 fortran-comment-indent-char
                    568:                 (char-to-string fortran-comment-indent-char))))
                    569:          ((looking-at "     [^ 0\n]")
                    570:           (goto-char (match-end 0)))
                    571:          (t
                    572:           ;; Move past line number.
                    573:           (move-to-column 5)))
                    574:     ;; Move past whitespace.
                    575:     (skip-chars-forward " \t")
                    576:     (current-column)))
                    577: 
                    578: (defun fortran-indent-to-column (col)
                    579:   "Indents current line with spaces to column COL.
                    580: notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
                    581:           line, and this continuation character is retained on indentation;
                    582:        2) If fortran-continuation-char is the first non-whitespace character,
                    583:           this is a continuation line;
                    584:        3) A non-continuation line which has a number as the first
                    585:           non-whitespace character is a numbered line."
                    586:   (save-excursion
                    587:     (beginning-of-line)
                    588:     (if (looking-at comment-line-start-skip)
                    589:        (if fortran-comment-indent-style
                    590:            (let ((char (if (stringp fortran-comment-indent-char)
                    591:                            (aref fortran-comment-indent-char 0)
                    592:                            fortran-comment-indent-char)))
                    593:              (goto-char (match-end 0))
                    594:              (delete-horizontal-regexp (concat " \t" (char-to-string char)))
                    595:              (insert-char char (- col (current-column)))))
                    596:       (if (looking-at "     [^ 0\n]")
                    597:          (forward-char 6)
                    598:        (delete-horizontal-space)
                    599:        ;; Put line number in columns 0-4
                    600:        ;; or put continuation character in column 5.
                    601:        (cond ((eobp))
                    602:              ((= (following-char) fortran-continuation-char)
                    603:               (indent-to 5)
                    604:               (forward-char 1))
                    605:              ((looking-at "[0-9]+")
                    606:               (let ((extra-space (- 5 (- (match-end 0) (point)))))
                    607:                 (if (< extra-space 0)
                    608:                     (message "Warning: line number exceeds 5-digit limit.")
                    609:                   (indent-to (min fortran-line-number-indent extra-space))))
                    610:               (skip-chars-forward "0-9"))))
                    611:       ;; Point is now after any continuation character or line number.
                    612:       ;; Put body of statement where specified.
                    613:       (delete-horizontal-space)
                    614:       (indent-to col)
                    615:       ;; Indent any comment following code on the same line.
                    616:       (if (re-search-forward comment-start-skip
                    617:                             (save-excursion (end-of-line) (point)) t)
                    618:          (progn (goto-char (match-beginning 0))
                    619:                 (if (not (= (current-column) (fortran-comment-hook)))
                    620:                     (progn (delete-horizontal-space)
                    621:                            (indent-to (fortran-comment-hook)))))))))
                    622: 
                    623: (defun fortran-line-number-indented-correctly-p ()
                    624:   "Return t if current line's line number is correctly indente.
                    625: Do not call if there is no line number."
                    626:   (save-excursion
                    627:     (beginning-of-line)
                    628:     (skip-chars-forward " \t")
                    629:     (and (<= (current-column) fortran-line-number-indent)
                    630:         (or (= (current-column) fortran-line-number-indent)
                    631:             (progn (skip-chars-forward "0-9")
                    632:                    (= (current-column) 5))))))
                    633: 
                    634: (defun fortran-check-for-matching-do ()
                    635:   "When called from a numbered statement, returns t
                    636:  if matching 'do' is found, and nil otherwise."
                    637:   (let (charnum
                    638:        (case-fold-search t))
                    639:     (save-excursion
                    640:       (beginning-of-line)
                    641:       (if (looking-at "[ \t]*[0-9]+")
                    642:          (progn
                    643:            (skip-chars-forward " \t")
                    644:            (skip-chars-forward "0") ;skip past leading zeros
                    645:            (setq charnum (buffer-substring (point)
                    646:                                            (progn (skip-chars-forward "0-9")
                    647:                                                   (point))))
                    648:            (beginning-of-line)
                    649:            (and (re-search-backward
                    650:                  (concat "\\(^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]\\)\\|\\(^[ \t0-9]*do[ \t]*0*"
                    651:                          charnum "\\b\\)\\|\\(^[ \t]*0*" charnum "\\b\\)")
                    652:                  nil t)
                    653:                 (looking-at (concat "^[ \t0-9]*do[ \t]*0*" charnum))))))))
                    654: 
                    655: 

unix.superglobalmegacorp.com

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