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

unix.superglobalmegacorp.com

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