comparison lisp/progmodes/fortran.el @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents fb628fd7f726
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 ;;; fortran.el --- Fortran mode for GNU Emacs 1 ;;; fortran.el --- Fortran mode for GNU Emacs
2 2
3 ;; Copyright (c) 1986, 93, 94, 95, 97, 98, 99, 2000, 2001 3 ;; Copyright (C) 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
4 ;; Free Software Foundation, Inc. 4 ;; 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 5
6 ;; Author: Michael D. Prange <prange@erl.mit.edu> 6 ;; Author: Michael D. Prange <prange@erl.mit.edu>
7 ;; Maintainer: Glenn Morris <gmorris@ast.cam.ac.uk> 7 ;; Maintainer: Glenn Morris <rgm@gnu.org>
8 ;; Keywords: languages 8 ;; Keywords: fortran, languages
9 9
10 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
11 11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify 12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by 13 ;; it under the terms of the GNU General Public License as published by
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details. 20 ;; GNU General Public License for more details.
21 21
22 ;; You should have received a copy of the GNU General Public License 22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the 23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02111-1307, USA. 25 ;; Boston, MA 02110-1301, USA.
26 26
27 ;;; Commentary: 27 ;;; Commentary:
28 28
29 ;; This mode is documented in the Emacs manual. 29 ;; This mode is documented in the Emacs manual.
30 ;; 30 ;;
51 ;; * Implement insertion and removal of statement continuations in 51 ;; * Implement insertion and removal of statement continuations in
52 ;; mixed f77/f90 style, with the first `&' past column 72 and the 52 ;; mixed f77/f90 style, with the first `&' past column 72 and the
53 ;; second in column 6. 53 ;; second in column 6.
54 ;; * Support any other extensions to f77 grokked by GNU Fortran I've missed. 54 ;; * Support any other extensions to f77 grokked by GNU Fortran I've missed.
55 55
56 (eval-when-compile ; silence compiler
57 (defvar dabbrev-case-fold-search)
58 (defvar font-lock-syntactic-keywords)
59 (defvar gud-find-expr-function)
60 (defvar imenu-case-fold-search)
61 (defvar imenu-syntax-alist))
62
63
56 (defgroup fortran nil 64 (defgroup fortran nil
57 "Fortran mode for Emacs" 65 "Major mode for editing fixed format Fortran code."
66 :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
58 :link '(custom-manual "(emacs)Fortran") 67 :link '(custom-manual "(emacs)Fortran")
59 :group 'languages) 68 :group 'languages)
60 69
61 (defgroup fortran-indent nil 70 (defgroup fortran-indent nil
62 "Indentation variables in Fortran mode" 71 "Indentation variables in Fortran mode."
63 :prefix "fortran-" 72 :prefix "fortran-"
64 :group 'fortran) 73 :group 'fortran)
65 74
66 (defgroup fortran-comment nil 75 (defgroup fortran-comment nil
67 "Comment-handling variables in Fortran mode" 76 "Comment-handling variables in Fortran mode."
68 :prefix "fortran-" 77 :prefix "fortran-"
69 :group 'fortran) 78 :group 'fortran)
70 79
71 80
72 ;;;###autoload 81 ;;;###autoload
73 (defcustom fortran-tab-mode-default nil 82 (defcustom fortran-tab-mode-default nil
74 "*Default tabbing/carriage control style for empty files in Fortran mode. 83 "*Default tabbing/carriage control style for empty files in Fortran mode.
75 A value of t specifies tab-digit style of continuation control. 84 A non-nil value specifies tab-digit style of continuation control.
76 A value of nil specifies that continuation lines are marked 85 A value of nil specifies that continuation lines are marked
77 with a character in column 6." 86 with a character in column 6."
78 :type 'boolean 87 :type 'boolean
79 :group 'fortran-indent) 88 :group 'fortran-indent)
80 89
81 ;; Buffer local, used to display mode line. 90 (defcustom fortran-tab-mode-string "/t"
82 (defcustom fortran-tab-mode-string nil 91 "*String to appear in mode line in TAB format buffers."
83 "String to appear in mode line when TAB format mode is on." 92 :type 'string
84 :type '(choice (const nil) string)
85 :group 'fortran-indent) 93 :group 'fortran-indent)
86 (make-variable-buffer-local 'fortran-tab-mode-string)
87 94
88 (defcustom fortran-do-indent 3 95 (defcustom fortran-do-indent 3
89 "*Extra indentation applied to DO blocks." 96 "*Extra indentation applied to DO blocks."
90 :type 'integer 97 :type 'integer
91 :group 'fortran-indent) 98 :group 'fortran-indent)
92 99
93 (defcustom fortran-if-indent 3 100 (defcustom fortran-if-indent 3
94 "*Extra indentation applied to IF blocks." 101 "*Extra indentation applied to IF, SELECT CASE and WHERE blocks."
95 :type 'integer 102 :type 'integer
96 :group 'fortran-indent) 103 :group 'fortran-indent)
97 104
98 (defcustom fortran-structure-indent 3 105 (defcustom fortran-structure-indent 3
99 "*Extra indentation applied to STRUCTURE, UNION, MAP and INTERFACE blocks." 106 "*Extra indentation applied to STRUCTURE, UNION, MAP and INTERFACE blocks."
100 :type 'integer 107 :type 'integer
101 :group 'fortran-indent) 108 :group 'fortran-indent)
102 109
103 (defcustom fortran-continuation-indent 5 110 (defcustom fortran-continuation-indent 5
104 "*Extra indentation applied to Fortran continuation lines." 111 "*Extra indentation applied to continuation lines."
105 :type 'integer 112 :type 'integer
106 :group 'fortran-indent) 113 :group 'fortran-indent)
107 114
108 (defcustom fortran-comment-indent-style 'fixed 115 (defcustom fortran-comment-indent-style 'fixed
109 "*How to indent comments. 116 "*How to indent comments.
110 nil forces comment lines not to be touched, 117 nil forces comment lines not to be touched;
111 `fixed' makes fixed comment indentation to `fortran-comment-line-extra-indent' 118 `fixed' indents to `fortran-comment-line-extra-indent' columns beyond
112 columns beyond `fortran-minimum-statement-indent-fixed' (for 119 `fortran-minimum-statement-indent-fixed' (if `indent-tabs-mode' nil), or
113 `indent-tabs-mode' of nil) or `fortran-minimum-statement-indent-tab' (for 120 `fortran-minimum-statement-indent-tab' (if `indent-tabs-mode' non-nil);
114 `indent-tabs-mode' of t), and
115 `relative' indents to current Fortran indentation plus 121 `relative' indents to current Fortran indentation plus
116 `fortran-comment-line-extra-indent'." 122 `fortran-comment-line-extra-indent'."
117 :type '(radio (const :tag "Untouched" nil) (const fixed) (const relative)) 123 :type '(radio (const :tag "Untouched" nil) (const fixed) (const relative))
118 :group 'fortran-indent) 124 :group 'fortran-indent)
119 125
120 (defcustom fortran-comment-line-extra-indent 0 126 (defcustom fortran-comment-line-extra-indent 0
121 "*Amount of extra indentation for text within full-line comments." 127 "*Amount of extra indentation for text within full-line comments."
122 :type 'integer 128 :type 'integer
123 :group 'fortran-indent 129 :group 'fortran-indent
124 :group 'fortran-comment) 130 :group 'fortran-comment)
125 131
126 (defcustom fortran-comment-line-start "C" 132 (defcustom fortran-comment-line-start "C"
127 "*Delimiter inserted to start new full-line comment. 133 "*Delimiter inserted to start new full-line comment.
128 You might want to change this to \"*\", for instance." 134 You might want to change this to \"*\", for instance."
129 :version "21.1" 135 :version "21.1"
130 :type 'string 136 :type 'string
131 :group 'fortran-comment) 137 :group 'fortran-comment)
132 138
133 ;; This used to match preprocessor lines too, but that messes up 139 ;; This used to match preprocessor lines too, but that messes up
134 ;; filling and doesn't seem to be necessary. 140 ;; filling and doesn't seem to be necessary.
135 (defcustom fortran-comment-line-start-skip 141 (defcustom fortran-comment-line-start-skip
136 "^[CcDd*!]\\(\\([^ \t\n]\\)\\2+\\)?[ \t]*" 142 "^[CcDd*!]\\(\\([^ \t\n]\\)\\2+\\)?[ \t]*"
137 "*Regexp to match the start of a full-line comment." 143 "*Regexp to match the start of a full-line comment."
138 :version "21.1" 144 :version "21.1"
139 :type 'regexp 145 :type 'regexp
140 :group 'fortran-comment) 146 :group 'fortran-comment)
141 147
142 (defcustom fortran-directive-re 148 (defcustom fortran-directive-re
143 "^[ \t]*#.*" 149 "^[ \t]*#.*"
144 "*Regexp to match a directive line. 150 "*Regexp to match a directive line.
145 The matching text will be fontified with `font-lock-keyword-face'. 151 The matching text will be fontified with `font-lock-keyword-face'.
146 The matching line will be given zero indentation." 152 The matching line will be given zero indentation."
147 :version "21.4" 153 :version "22.1"
148 :type 'regexp 154 :type 'regexp
149 :group 'fortran-indent) 155 :group 'fortran-indent)
150 156
151 (defcustom fortran-minimum-statement-indent-fixed 6 157 (defcustom fortran-minimum-statement-indent-fixed 6
152 "*Minimum statement indentation for fixed format continuation style." 158 "*Minimum statement indentation for fixed format continuation style."
153 :type 'integer 159 :type 'integer
154 :group 'fortran-indent) 160 :group 'fortran-indent)
155 161
156 (defcustom fortran-minimum-statement-indent-tab (max tab-width 6) 162 (defcustom fortran-minimum-statement-indent-tab (max tab-width 6)
157 "*Minimum statement indentation for TAB format continuation style." 163 "*Minimum statement indentation for TAB format continuation style."
158 :type 'integer 164 :type 'integer
159 :group 'fortran-indent) 165 :group 'fortran-indent)
160 166
161 ;; Note that this is documented in the v18 manuals as being a string 167 ;; Note that this is documented in the v18 manuals as being a string
162 ;; of length one rather than a single character. 168 ;; of length one rather than a single character.
163 ;; The code in this file accepts either format for compatibility. 169 ;; The code in this file accepts either format for compatibility.
164 (defcustom fortran-comment-indent-char " " 170 (defcustom fortran-comment-indent-char " "
165 "*Single-character string inserted for Fortran comment indentation. 171 "*Single-character string inserted for Fortran comment indentation.
166 Normally a space." 172 Normally a space."
167 :type 'string 173 :type 'string
168 :group 'fortran-comment) 174 :group 'fortran-comment)
169 175
170 (defcustom fortran-line-number-indent 1 176 (defcustom fortran-line-number-indent 1
171 "*Maximum indentation for Fortran line numbers. 177 "*Maximum indentation for Fortran line numbers.
172 5 means right-justify them within their five-column field." 178 5 means right-justify them within their five-column field."
173 :type 'integer 179 :type 'integer
174 :group 'fortran-indent) 180 :group 'fortran-indent)
175 181
176 (defcustom fortran-check-all-num-for-matching-do nil 182 (defcustom fortran-check-all-num-for-matching-do nil
177 "*Non-nil causes all numbered lines to be treated as possible DO loop ends." 183 "*Non-nil causes all numbered lines to be treated as possible DO loop ends."
178 :type 'boolean 184 :type 'boolean
179 :group 'fortran) 185 :group 'fortran)
180 186
181 (defcustom fortran-blink-matching-if nil 187 (defcustom fortran-blink-matching-if nil
182 "*Non-nil causes \\[fortran-indent-line] on ENDIF statement to blink on matching IF. 188 "*Non-nil causes \\[fortran-indent-line] on ENDIF to blink on matching IF.
183 Also, from an ENDDO statement blink on matching DO [WHILE] statement." 189 Also, from an ENDDO statement blink on matching DO [WHILE] statement."
184 :type 'boolean 190 :type 'boolean
185 :group 'fortran) 191 :group 'fortran)
186 192
187 (defcustom fortran-continuation-string "$" 193 (defcustom fortran-continuation-string "$"
188 "*Single-character string used for Fortran continuation lines. 194 "*Single-character string used for Fortran continuation lines.
189 In fixed format continuation style, this character is inserted in 195 In fixed format continuation style, this character is inserted in
190 column 6 by \\[fortran-split-line] to begin a continuation line. 196 column 6 by \\[fortran-split-line] to begin a continuation line.
191 Also, if \\[fortran-indent-line] finds this at the beginning of a line, it will 197 Also, if \\[fortran-indent-line] finds this at the beginning of a
192 convert the line into a continuation line of the appropriate style. 198 line, it will convert the line into a continuation line of the
193 Normally $." 199 appropriate style. Normally $."
194 :type 'string 200 :type 'string
195 :group 'fortran) 201 :group 'fortran)
196 202
197 (defcustom fortran-comment-region "c$$$" 203 (defcustom fortran-comment-region "c$$$"
198 "*String inserted by \\[fortran-comment-region] at start of each \ 204 "*String inserted by \\[fortran-comment-region] at start of each \
199 line in region." 205 line in region."
200 :type 'string 206 :type 'string
201 :group 'fortran-comment) 207 :group 'fortran-comment)
202 208
203 (defcustom fortran-electric-line-number t 209 (defcustom fortran-electric-line-number t
204 "*Non-nil causes line number digits to be moved to the correct \ 210 "*Non-nil causes line numbers to be moved to the correct column as typed."
205 column as typed." 211 :type 'boolean
206 :type 'boolean
207 :group 'fortran) 212 :group 'fortran)
208 213
209 (defvar fortran-column-ruler-fixed 214 (defcustom fortran-column-ruler-fixed
210 "0 4 6 10 20 30 40 5\ 215 "0 4 6 10 20 30 40 5\
211 0 60 70\n\ 216 0 60 70\n\
212 \[ ]|{ | | | | | | | | \ 217 \[ ]|{ | | | | | | | | \
213 \| | | | |}\n" 218 \| | | | |}\n"
214 "String displayed above current line by \\[fortran-column-ruler]. 219 "String displayed above current line by \\[fortran-column-ruler].
215 This variable used in fixed format mode.") 220 This variable is used in fixed format mode.
216 221 See the variable `fortran-column-ruler-tab' for TAB format mode."
217 (defvar fortran-column-ruler-tab 222 :type 'string
223 :group 'fortran)
224
225 (defcustom fortran-column-ruler-tab
218 "0 810 20 30 40 5\ 226 "0 810 20 30 40 5\
219 0 60 70\n\ 227 0 60 70\n\
220 \[ ]| { | | | | | | | | \ 228 \[ ]| { | | | | | | | | \
221 \| | | | |}\n" 229 \| | | | |}\n"
222 "String displayed above current line by \\[fortran-column-ruler]. 230 "String displayed above current line by \\[fortran-column-ruler].
223 This variable used in TAB format mode.") 231 This variable is used in TAB format mode.
224 232 See the variable `fortran-column-ruler-fixed' for fixed format mode."
225 (defvar fortran-analyze-depth 100 233 :type 'string
226 "Number of lines to scan to determine whether to use fixed or TAB \ 234 :group 'fortran)
227 format style.") 235
236 (defcustom fortran-analyze-depth 100
237 "Number of lines to scan to identify fixed or TAB format style."
238 :type 'integer
239 :group 'fortran)
228 240
229 (defcustom fortran-break-before-delimiters t 241 (defcustom fortran-break-before-delimiters t
230 "*Non-nil causes filling to break lines before delimiters." 242 "*Non-nil causes filling to break lines before delimiters.
231 :type 'boolean 243 Delimiters are characters matching the regexp `fortran-break-delimiters-re'."
244 :type 'boolean
232 :group 'fortran) 245 :group 'fortran)
233 246
234 (defvar fortran-mode-syntax-table 247 (defconst fortran-break-delimiters-re "[-+*/><=, \t]"
235 (let ((table (make-syntax-table))) 248 "Regexp matching delimiter characters at which lines may be broken.
236 ;; We might like `;' to be punctuation (g77 multi-statement 249 There are certain tokens comprised entirely of characters
237 ;; lines), but that screws abbrevs. 250 matching this regexp that should not be split, and these are
238 (modify-syntax-entry ?\; "w" table) 251 specified by the constant `fortran-no-break-re'.")
239 (modify-syntax-entry ?\r " " table) 252
240 (modify-syntax-entry ?+ "." table) 253 ;; The ">=", etc F77 extensions are supported by g77.
241 (modify-syntax-entry ?- "." table) 254 (defconst fortran-no-break-re
242 (modify-syntax-entry ?= "." table) 255 (regexp-opt '("**" "//" "=>" ">=" "<=" "==" "/=") 'paren)
243 (modify-syntax-entry ?* "." table) 256 "Regexp specifying where not to break lines when filling.
244 (modify-syntax-entry ?/ "." table) 257 This regexp matches certain tokens comprised entirely of
245 (modify-syntax-entry ?\' "\"" table) 258 characters matching the regexp `fortran-break-delimiters-re' that should
246 (modify-syntax-entry ?\" "\"" table) 259 not be split by filling. Each element is assumed to be two
247 ;; Consistent with GNU Fortran -- see the manual. 260 characters long.")
248 (modify-syntax-entry ?\\ "\\" table) 261
249 ;; This might be better as punctuation, as for C, but this way you 262 (defcustom fortran-mode-hook nil
250 ;; can treat floating-point numbers as symbols. 263 "Hook run when entering Fortran mode."
251 (modify-syntax-entry ?. "_" table) ; e.g. `a.ne.b' 264 :type 'hook
252 (modify-syntax-entry ?_ "_" table) 265 :group 'fortran)
253 (modify-syntax-entry ?$ "_" table) ; esp. VMSisms 266
254 (modify-syntax-entry ?\! "<" table) 267
255 (modify-syntax-entry ?\n ">" table) 268 (defvar fortran-if-start-re "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*("
256 table) 269 "Regexp matching the start of an IF statement.")
257 "Syntax table in use in Fortran mode buffers.") 270
271 (defvar fortran-end-prog-re1
272 "end\
273 \\([ \t]*\\(program\\|subroutine\\|function\\|block[ \t]*data\\)\\>\
274 \\([ \t]*\\(\\sw\\|\\s_\\)+\\)?\\)?"
275 "Regexp possibly matching the end of a subprogram.")
276
277 (defvar fortran-end-prog-re
278 (concat "^[ \t0-9]*" fortran-end-prog-re1)
279 "Regexp possibly matching the end of a subprogram, from the line start.
280 See also `fortran-end-prog-re1'.")
281
282 (defconst fortran-type-types
283 (concat "\\<"
284 (mapconcat 'identity ; " " -> "[ \t]*"
285 (split-string
286 (regexp-opt
287 (let ((simple-types
288 '("character" "byte" "integer" "logical"
289 "none" "real" "complex"
290 "double precision" "double complex"))
291 (structured-types '("structure" "union" "map"))
292 (other-types '("record" "dimension"
293 "parameter" "common" "save"
294 "external" "intrinsic" "data"
295 "equivalence")))
296 (append
297 (mapcar (lambda (x) (concat "implicit " x))
298 simple-types)
299 simple-types
300 (mapcar (lambda (x) (concat "end " x))
301 structured-types)
302 structured-types
303 other-types)) 'paren))
304 "[ \t]*") "\\>")
305 "Regexp matching Fortran types.")
306
307 (defvar fortran-font-lock-keywords-1
308 ;; Program, subroutine and function declarations, plus calls.
309 '(("\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|\
310 program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?"
311 (1 font-lock-keyword-face)
312 (2 font-lock-function-name-face nil t)))
313 "Subdued level highlighting for Fortran mode.")
314
315 (defvar fortran-font-lock-keywords-2
316 (append fortran-font-lock-keywords-1
317 (list
318 ;; Fontify all type specifiers (must be first - see below).
319 (cons fortran-type-types 'font-lock-type-face)
320 ;; Builtin keywords (except logical, do and goto - see below).
321 (concat "\\<" (regexp-opt
322 '("continue" "format" "end" "enddo"
323 "if" "then" "else" "endif" "elseif"
324 "while" "inquire" "stop" "return"
325 "include" "open" "close" "read"
326 "write" "format" "print" "select" "case"
327 "cycle" "exit" "rewind" "backspace"
328 "where" "elsewhere")
329 'paren) "\\>")
330 ;; Builtin operators.
331 (concat "\\." (regexp-opt
332 '("and" "or" "not" "lt" "le" "eq" "ge"
333 "gt" "ne" "true" "false")
334 'paren) "\\.")
335 ;; do/goto keywords and targets, and goto tags.
336 '("\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?"
337 (1 font-lock-keyword-face)
338 (2 font-lock-constant-face nil t))
339 '("^ *\\([0-9]+\\)" . font-lock-constant-face)))
340 "Medium level highlighting for Fortran mode.")
341
342 (defvar fortran-font-lock-keywords-3
343 (append
344 fortran-font-lock-keywords-1
345 ;; All type specifiers plus their declared items.
346 (list
347 (list (concat fortran-type-types "[ \t(/]*\\(*\\)?")
348 ;; Type specifier.
349 '(1 font-lock-type-face)
350 ;; Declaration item (or just /.../ block name).
351 `(font-lock-match-c-style-declaration-item-and-skip-to-next
352 ;; Start after any *(...) expression.
353 (condition-case nil
354 (and (match-beginning ,(1+ (regexp-opt-depth
355 fortran-type-types)))
356 (forward-sexp)
357 (forward-sexp))
358 (error nil))
359 ;; No need to clean up.
360 nil
361 ;; Fontify as a variable name, functions fontified elsewhere.
362 (1 font-lock-variable-name-face nil t))))
363 ;; Things extra to `fortran-font-lock-keywords-3' (must be done first).
364 (list
365 ;; Goto-like `err=label'/`end=label' in read/write statements.
366 '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?"
367 (1 font-lock-keyword-face) (4 font-lock-constant-face nil t))
368 ;; Standard continuation character and in a TAB-formatted line.
369 '("^ \\{5\\}\\([^ 0\n]\\)" 1 font-lock-string-face)
370 '("^\t\\([1-9]\\)" 1 font-lock-string-face))
371 `((,fortran-directive-re (0 font-lock-keyword-face t)))
372 ;; `fortran-font-lock-keywords-2' without types (see above).
373 (cdr (nthcdr (length fortran-font-lock-keywords-1)
374 fortran-font-lock-keywords-2)))
375 "Gaudy level highlighting for Fortran mode.")
376
377 (defvar fortran-font-lock-keywords-4
378 (append fortran-font-lock-keywords-3
379 (list (list
380 (concat "\\<"
381 (regexp-opt
382 '("int" "ifix" "idint" "real" "float" "sngl"
383 "dble" "cmplx" "ichar" "char" "aint" "dint"
384 "anint" "dnint" "nint" "idnint" "iabs" "abs"
385 "dabs" "cabs" "mod" "amod" "dmod" "isign"
386 "sign" "dsign" "idim" "dim" "ddim" "dprod"
387 "max" "max0" "amax1" "dmax1" "amax0" "max1"
388 "min0" "amin1" "dmin1" "amin0" "min1" "len"
389 "index" "lge" "lgt" "lle" "llt" "aimag"
390 "conjg" "sqrt" "dsqrt" "csqrt" "exp" "dexp"
391 "cexp" "log" "alog" "dlog" "clog" "log10"
392 "alog10" "dlog10" "sin" "dsin" "csin" "cos"
393 "dcos" "ccos" "tan" "dtan" "asin" "dasin"
394 "acos" "dacos" "atan" "datan" "atan2" "datan2"
395 "sinh" "dsinh" "cosh" "dcosh" "tanh" "dtanh")
396 'paren) "[ \t]*(") '(1 font-lock-builtin-face))))
397 "Maximum highlighting for Fortran mode.
398 Consists of level 3 plus all other intrinsics not already highlighted.")
258 399
259 ;; Comments are real pain in Fortran because there is no way to 400 ;; Comments are real pain in Fortran because there is no way to
260 ;; represent the standard comment syntax in an Emacs syntax table. 401 ;; represent the standard comment syntax in an Emacs syntax table.
261 ;; (We can do so for F90-style). Therefore an unmatched quote in a 402 ;; (We can do so for F90-style). Therefore an unmatched quote in a
262 ;; standard comment will throw fontification off on the wrong track. 403 ;; standard comment will throw fontification off on the wrong track.
263 ;; So we do syntactic fontification with regexps. 404 ;; So we do syntactic fontification with regexps.
264 405 (defvar fortran-font-lock-syntactic-keywords
265 (defvar fortran-font-lock-keywords-1 nil 406 '(("^[cd\\*]" 0 (11))
266 "Subdued level highlighting for Fortran mode.") 407 ("^[^cd\\*\t\n].\\{71\\}\\([^\n]+\\)" 1 (11)))
267
268 (defvar fortran-font-lock-keywords-2 nil
269 "Medium level highlighting for Fortran mode.")
270
271 (defvar fortran-font-lock-keywords-3 nil
272 "Gaudy level highlighting for Fortran mode.")
273
274 (defvar fortran-font-lock-syntactic-keywords nil
275 "`font-lock-syntactic-keywords' for Fortran. 408 "`font-lock-syntactic-keywords' for Fortran.
276 These get fixed-format comments fontified.") 409 These get fixed-format comments fontified.")
277 410
278 (let ((comment-chars "cd\\*") ; `d' for `debugging' comments
279 (fortran-type-types
280 (eval-when-compile
281 (let ((re (regexp-opt
282 (let ((simple-types
283 '("character" "byte" "integer" "logical"
284 "none" "real" "complex"
285 "double precision" "double complex"))
286 (structured-types '("structure" "union" "map"))
287 (other-types '("record" "dimension"
288 "parameter" "common" "save"
289 "external" "intrinsic" "data"
290 "equivalence")))
291 (append
292 (mapcar (lambda (x) (concat "implicit " x))
293 simple-types)
294 simple-types
295 (mapcar (lambda (x) (concat "end " x))
296 structured-types)
297 structured-types
298 other-types)))))
299 ;; In the optimized regexp above, replace spaces by a
300 ;; regexp for optional whitespace; regexp-opt would have
301 ;; escaped that.
302 (mapconcat #'identity (split-string re) "[ \t]*"))))
303 (fortran-keywords
304 (eval-when-compile
305 (regexp-opt '("continue" "format" "end" "enddo" "if" "then"
306 "else" "endif" "elseif" "while" "inquire" "stop"
307 "return" "include" "open" "close" "read" "write"
308 "format" "print" "select" "case" "cycle" "exit"
309 "rewind" "backspace"))))
310 (fortran-logicals
311 (eval-when-compile
312 (regexp-opt '("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne"
313 "true" "false")))))
314 (setq fortran-font-lock-syntactic-keywords
315 ;; Fixed format comments. (!-style handled normally.)
316 (list
317 (list (concat "^[" comment-chars "]") 0 '(11))
318 (list (concat "^[^" comment-chars "\t\n]" ".\\{71\\}"
319 "\\([^\n]+\\)")
320 1 '(11))))
321 (setq fortran-font-lock-keywords-1
322 (list
323 ;; Program, subroutine and function declarations, plus calls.
324 (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|"
325 "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?")
326 '(1 font-lock-keyword-face)
327 '(2 font-lock-function-name-face nil t))))
328 (setq fortran-font-lock-keywords-2
329 (append fortran-font-lock-keywords-1
330 (list
331 ;; Fontify all type specifiers (must be first; see below).
332 (cons (concat "\\<\\(" fortran-type-types "\\)\\>")
333 'font-lock-type-face)
334 ;; Fontify all builtin keywords (except logical, do
335 ;; and goto; see below).
336 (concat "\\<\\(" fortran-keywords "\\)\\>")
337 ;; Fontify all builtin operators.
338 (concat "\\.\\(" fortran-logicals "\\)\\.")
339 ;; Fontify do/goto keywords and targets, and goto tags.
340 (list "\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?"
341 '(1 font-lock-keyword-face)
342 '(2 font-lock-constant-face nil t))
343 (cons "^ *\\([0-9]+\\)" 'font-lock-constant-face))))
344 (setq fortran-font-lock-keywords-3
345 (append
346 ;; The list `fortran-font-lock-keywords-1'.
347 fortran-font-lock-keywords-1
348 ;; Fontify all type specifiers plus their declared items.
349 (list
350 (list (concat "\\<\\(" fortran-type-types "\\)\\>[ \t(/]*\\(*\\)?")
351 ;; Fontify the type specifier.
352 '(1 font-lock-type-face)
353 ;; Fontify each declaration item (or just the /.../ block name).
354 `(font-lock-match-c-style-declaration-item-and-skip-to-next
355 ;; Start after any *(...) expression.
356 (condition-case nil
357 (and (and (match-beginning ,(+ 2 (regexp-opt-depth
358 fortran-type-types)))
359 (forward-sexp))
360 (forward-sexp))
361 (error nil))
362 ;; No need to clean up.
363 nil
364 ;; Fontify as a variable name, functions are
365 ;; fontified elsewhere.
366 (1 font-lock-variable-name-face nil t))))
367 ;; Things extra to `fortran-font-lock-keywords-3'
368 ;; (must be done first).
369 (list
370 ;; Fontify goto-like `err=label'/`end=label' in read/write
371 ;; statements.
372 '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?"
373 (1 font-lock-keyword-face) (4 font-lock-constant-face nil t))
374 ;; Highlight standard continuation character and in a
375 ;; TAB-formatted line.
376 '("^ \\([^ 0]\\)" 1 font-lock-string-face)
377 '("^\t\\([1-9]\\)" 1 font-lock-string-face))
378 (list
379 ;; cpp stuff (ugh)
380 ;;; '("^# *[a-z]+" . font-lock-keyword-face))
381 `(,fortran-directive-re (0 font-lock-keyword-face t)))
382 ;; The list `fortran-font-lock-keywords-2' less that for types
383 ;; (see above).
384 (cdr (nthcdr (length fortran-font-lock-keywords-1)
385 fortran-font-lock-keywords-2)))))
386
387 (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 411 (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1
388 "Default expressions to highlight in Fortran mode.") 412 "Default expressions to highlight in Fortran mode.")
389 413
390 (defvar fortran-imenu-generic-expression 414 (defvar fortran-imenu-generic-expression
391 ;; These patterns could be confused by sequence nos. in cols 72+ and 415 ;; These patterns could be confused by sequence nos. in cols 72+ and
392 ;; don't allow continuations everywhere. 416 ;; don't allow continuations everywhere.
393 (list 417 (list
394 (list 418 (list
405 ;; Possible statement continuation: 429 ;; Possible statement continuation:
406 "[ \t" fortran-continuation-string "]+" 430 "[ \t" fortran-continuation-string "]+"
407 ;; Variable to index: 431 ;; Variable to index:
408 "\\(\\sw+\\)") 432 "\\(\\sw+\\)")
409 3) 433 3)
410 ;; Un-named block data 434 ;; Un-named block data.
411 (list nil "^\\s-+\\(block\\s-*data\\)\\s-*$" 1)) 435 '(nil "^\\s-+\\(block\\s-*data\\)\\s-*$" 1))
412 "Imenu generic expression for `imenu-default-create-index-function'.") 436 "Value for `imenu-generic-expression' in Fortran mode.")
437
438
439 ;; Hideshow support.
440 (defconst fortran-blocks-re
441 (concat "block[ \t]*data\\|select[ \t]*case\\|"
442 (regexp-opt '("do" "if" "interface" "function" "map" "program"
443 "structure" "subroutine" "union" "where")))
444 "Regexp potentially indicating the start or end of a Fortran \"block\".
445 Omits naked END statements, and DO-loops closed by anything other
446 than ENDDO.")
447
448 (defconst fortran-end-block-re
449 ;; Do-loops terminated by things other than ENDDO cannot be handled
450 ;; with a regexp. This omission does not seem to matter to hideshow...
451 (concat "^[ \t0-9]*\\<end[ \t]*\\("
452 fortran-blocks-re
453 ;; Naked END statement.
454 "\\|!\\|$\\)")
455 "Regexp matching the end of a Fortran \"block\", from the line start.
456 Note that only ENDDO is handled for the end of a DO-loop. Used
457 in the Fortran entry in `hs-special-modes-alist'.")
458
459 (defconst fortran-start-block-re
460 (concat
461 "^[ \t0-9]*\\(" ; statement number
462 ;; Structure label for DO, IF, SELECT, WHERE.
463 "\\(\\(\\sw+[ \t]*:[ \t]*\\)?"
464 ;; IF blocks are a nuisance:
465 ;; IF ( ... ) foo is not a block, but a single statement.
466 ;; IF ( ... ) THEN can be split over multiple lines.
467 ;; [So can, eg, a DO WHILE (... ), but that is less common, I hope.]
468 ;; The regexp below allows for it to be split over at most 2 lines.
469 ;; That leads to the problem of not matching two consecutive IF
470 ;; statements as one, eg:
471 ;; IF ( ... ) foo
472 ;; IF ( ... ) THEN
473 ;; It simply is not possible to do this in a 100% correct fashion
474 ;; using a regexp - see the functions fortran-end-if,
475 ;; fortran-beginning-if for the hoops we have to go through.
476 ;; An alternative is to match on THEN at a line end, eg:
477 ;; ".*)[ \t]*then[ \t]*\\($\\|!\\)"
478 ;; This would also match ELSE branches, though. This does not seem
479 ;; right to me, because then one has neighbouring blocks that are
480 ;; not nested in each other.
481 "\\(if[ \t]*(\\(.*\\|"
482 ".*\n\\([^if]*\\([^i].\\|.[^f]\\|.\\>\\)\\)\\)\\<then\\|"
483 "do\\|select[ \t]*case\\|where\\)\\)\\|"
484 (regexp-opt '("interface" "function" "map" "program"
485 "structure" "subroutine" "union"))
486 "\\|block[ \t]*data\\)[ \t]*")
487 "Regexp matching the start of a Fortran \"block\", from the line start.
488 A simple regexp cannot do this in fully correct fashion, so this
489 tries to strike a compromise between complexity and flexibility.
490 Used in the Fortran entry in `hs-special-modes-alist'.")
491
492 (add-to-list 'hs-special-modes-alist
493 `(fortran-mode ,fortran-start-block-re ,fortran-end-block-re
494 "^[cC*!]" fortran-end-of-block nil))
495
496
497 (defvar fortran-mode-syntax-table
498 (let ((table (make-syntax-table)))
499 ;; We might like `;' to be punctuation (g77 multi-statement
500 ;; lines), but that screws abbrevs.
501 (modify-syntax-entry ?\; "w" table)
502 (modify-syntax-entry ?\r " " table)
503 (modify-syntax-entry ?+ "." table)
504 (modify-syntax-entry ?- "." table)
505 (modify-syntax-entry ?= "." table)
506 (modify-syntax-entry ?* "." table)
507 (modify-syntax-entry ?/ "." table)
508 (modify-syntax-entry ?\' "\"" table)
509 (modify-syntax-entry ?\" "\"" table)
510 ;; Consistent with GNU Fortran's default -- see the manual.
511 ;; The F77 standard imposes no rule on this issue.
512 (modify-syntax-entry ?\\ "\\" table)
513 ;; This might be better as punctuation, as for C, but this way you
514 ;; can treat floating-point numbers as symbols.
515 (modify-syntax-entry ?. "_" table) ; e.g. `a.ne.b'
516 (modify-syntax-entry ?_ "_" table)
517 (modify-syntax-entry ?$ "_" table) ; esp. VMSisms
518 (modify-syntax-entry ?\! "<" table)
519 (modify-syntax-entry ?\n ">" table)
520 table)
521 "Syntax table used in Fortran mode.")
522
523 (defvar fortran-gud-syntax-table
524 (let ((st (make-syntax-table fortran-mode-syntax-table)))
525 (modify-syntax-entry ?\n "." st)
526 st)
527 "Syntax table used to parse Fortran expressions for printing in GUD.")
413 528
414 (defvar fortran-mode-map 529 (defvar fortran-mode-map
415 (let ((map (make-sparse-keymap))) 530 (let ((map (make-sparse-keymap)))
416 (define-key map ";" 'fortran-abbrev-start) 531 (define-key map ";" 'fortran-abbrev-start)
417 (define-key map "\C-c;" 'fortran-comment-region) 532 (define-key map "\C-c;" 'fortran-comment-region)
418 (define-key map "\M-;" 'fortran-indent-comment) 533 (define-key map "\M-;" 'fortran-indent-comment)
419 (define-key map "\M-\n" 'fortran-split-line) 534 (define-key map "\M-\n" 'fortran-split-line)
420 (define-key map "\M-\C-q" 'fortran-indent-subprogram) 535 (define-key map "\M-\C-n" 'fortran-end-of-block)
536 (define-key map "\M-\C-p" 'fortran-beginning-of-block)
537 (define-key map "\M-\C-q" 'fortran-indent-subprogram)
421 (define-key map "\C-c\C-w" 'fortran-window-create-momentarily) 538 (define-key map "\C-c\C-w" 'fortran-window-create-momentarily)
422 (define-key map "\C-c\C-r" 'fortran-column-ruler) 539 (define-key map "\C-c\C-r" 'fortran-column-ruler)
423 (define-key map "\C-c\C-p" 'fortran-previous-statement) 540 (define-key map "\C-c\C-p" 'fortran-previous-statement)
424 (define-key map "\C-c\C-n" 'fortran-next-statement) 541 (define-key map "\C-c\C-n" 'fortran-next-statement)
425 (define-key map "\C-c\C-d" 'fortran-join-line) ; like f90 542 (define-key map "\C-c\C-d" 'fortran-join-line) ; like f90
426 (define-key map "\M-^" 'fortran-join-line) ; subvert delete-indentation 543 (define-key map "\M-^" 'fortran-join-line) ; subvert delete-indentation
427 (define-key map "0" 'fortran-electric-line-number) 544 (define-key map "0" 'fortran-electric-line-number)
428 (define-key map "1" 'fortran-electric-line-number) 545 (define-key map "1" 'fortran-electric-line-number)
429 (define-key map "2" 'fortran-electric-line-number) 546 (define-key map "2" 'fortran-electric-line-number)
430 (define-key map "3" 'fortran-electric-line-number) 547 (define-key map "3" 'fortran-electric-line-number)
431 (define-key map "4" 'fortran-electric-line-number) 548 (define-key map "4" 'fortran-electric-line-number)
433 (define-key map "6" 'fortran-electric-line-number) 550 (define-key map "6" 'fortran-electric-line-number)
434 (define-key map "7" 'fortran-electric-line-number) 551 (define-key map "7" 'fortran-electric-line-number)
435 (define-key map "8" 'fortran-electric-line-number) 552 (define-key map "8" 'fortran-electric-line-number)
436 (define-key map "9" 'fortran-electric-line-number) 553 (define-key map "9" 'fortran-electric-line-number)
437 554
438 ;; Menu 555 (easy-menu-define fortran-menu map "Menu for Fortran mode."
439 (easy-menu-define 556 `("Fortran"
440 fortran-mode-menu map "" 557 ["Manual" (info "(emacs)Fortran")]
441 `("Fortran" 558 ("Customization"
442 ["Manual" (info "(emacs)Fortran")] 559 ,(custom-menu-create 'fortran)
443 ("Customization" 560 ["Set" Custom-set t]
444 ,(custom-menu-create 'fortran) 561 ["Save" Custom-save t]
445 ["Set" Custom-set t] 562 ["Reset to Current" Custom-reset-current t]
446 ["Save" Custom-save t] 563 ["Reset to Saved" Custom-reset-saved t]
447 ["Reset to Current" Custom-reset-current t] 564 ["Reset to Standard Settings" Custom-reset-standard t]
448 ["Reset to Saved" Custom-reset-saved t] 565 )
449 ["Reset to Standard Settings" Custom-reset-standard t]) 566 "--"
450 "----" 567 ["Comment Region" fortran-comment-region mark-active]
451 ["Toggle Auto-fill" auto-fill-mode :style toggle 568 ["Uncomment Region"
452 :selected auto-fill-function] 569 (fortran-comment-region (region-beginning) (region-end) 1)
453 ["Toggle abbrev-mode" abbrev-mode :style toggle :selected abbrev-mode] 570 mark-active]
454 "----" 571 ["Indent Region" indent-region mark-active]
455 ["Comment-out Region" fortran-comment-region mark-active] 572 ["Indent Subprogram" fortran-indent-subprogram t]
456 ["Uncomment-out region" 573 "--"
457 (fortran-comment-region (region-beginning) (region-end) 1) 574 ["Beginning of Subprogram" fortran-beginning-of-subprogram t]
458 mark-active] 575 ["End of Subprogram" fortran-end-of-subprogram t]
459 ["Indent Region" indent-region mark-active] 576 ("Mark"
460 ["Indent Subprogram" fortran-indent-subprogram t] 577 ["Subprogram" mark-defun t]
461 "----" 578 ["IF Block" fortran-mark-if t]
462 ["Beginning of Subprogram" fortran-beginning-of-subprogram t] 579 ["DO Block" fortran-mark-do t]
463 ["End of Subprogram" fortran-end-of-subprogram t] 580 )
464 ("Mark" 581 ["Narrow to Subprogram" narrow-to-defun t]
465 ["Subprogram" mark-defun t] 582 ["Widen" widen t]
466 ["IF Block" fortran-mark-if t] 583 "--"
467 ["DO Block" fortran-mark-do t]) 584 ["Temporary column ruler" fortran-column-ruler t]
468 ["Narrow to Subprogram" narrow-to-defun t] 585 ["72-column window" fortran-window-create t]
469 ["Widen" widen t] 586 ["Full Width Window"
470 "----" 587 (enlarge-window-horizontally (- (frame-width) (window-width)))
471 ["Temporary column ruler" fortran-column-ruler t] 588 (< (window-width) (frame-width))]
472 ["72-column window" fortran-window-create t] 589 ["Momentary 72-column window" fortran-window-create-momentarily t]
473 ["Full Width Window" 590 "--"
474 (enlarge-window-horizontally (- (frame-width) (window-width))) 591 ["Break Line at Point" fortran-split-line t]
475 (< (window-width) (frame-width))] 592 ["Join Line" fortran-join-line t]
476 ["Momentary 72-column window" fortran-window-create-momentarily t] 593 ["Fill Statement/Comment" fill-paragraph t]
477 "----" 594 "--"
478 ["Break Line at Point" fortran-split-line t] 595 ["Toggle auto-fill" auto-fill-mode :selected auto-fill-function
479 ["Join Line" fortran-join-line t] 596 :style toggle]
480 ["Fill Statement/Comment" fill-paragraph t] 597 ["Toggle abbrev-mode" abbrev-mode :selected abbrev-mode
481 "----" 598 :style toggle]
482 ["Add imenu menu" 599 ["Add imenu Menu" imenu-add-menubar-index
483 imenu-add-menubar-index (not (and (boundp 'imenu--index-alist) 600 :active (not (lookup-key (current-local-map) [menu-bar index]))
484 imenu--index-alist))])) 601 :included (fboundp 'imenu-add-to-menubar)]))
485 map) 602 map)
486 "Keymap used in Fortran mode.") 603 "Keymap used in Fortran mode.")
604
487 605
488 (defvar fortran-mode-abbrev-table 606 (defvar fortran-mode-abbrev-table
489 (let (abbrevs-changed) 607 (let (abbrevs-changed)
490 (define-abbrev-table 'fortran-mode-abbrev-table nil) 608 (define-abbrev-table 'fortran-mode-abbrev-table nil)
491 ;; Use the 6th arg (SYSTEM-FLAG) of define-abbrev if possible. 609 ;; Use the 6th arg (SYSTEM-FLAG) of define-abbrev if possible.
555 (";ty" "type" ) 673 (";ty" "type" )
556 (";vo" "volatile" ) 674 (";vo" "volatile" )
557 (";w" "write" ) 675 (";w" "write" )
558 (";wh" "where" ))) 676 (";wh" "where" )))
559 fortran-mode-abbrev-table)) 677 fortran-mode-abbrev-table))
678
560 679
561 (eval-when-compile ; silence compiler
562 (defvar imenu-case-fold-search)
563 (defvar imenu-syntax-alist))
564
565 (defcustom fortran-mode-hook nil
566 "Hook run by Fortran mode."
567 :type 'hook
568 :group 'fortran)
569 680
570 ;;;###autoload 681 ;;;###autoload
571 (defun fortran-mode () 682 (defun fortran-mode ()
572 "Major mode for editing Fortran code. 683 "Major mode for editing Fortran code in fixed format.
684 For free format code, use `f90-mode'.
685
573 \\[fortran-indent-line] indents the current Fortran line correctly. 686 \\[fortran-indent-line] indents the current Fortran line correctly.
574 DO statements must not share a common CONTINUE. 687 Note that DO statements must not share a common CONTINUE.
575 688
576 Type ;? or ;\\[help-command] to display a list of built-in abbrevs for 689 Type ;? or ;\\[help-command] to display a list of built-in abbrevs for\
577 Fortran keywords. 690 Fortran keywords.
578 691
579 Key definitions: 692 Key definitions:
580 \\{fortran-mode-map} 693 \\{fortran-mode-map}
581 694
582 Variables controlling indentation style and extra features: 695 Variables controlling indentation style and extra features:
583 696
584 `comment-start' 697 `fortran-comment-line-start'
585 If you want to use comments starting with `!', 698 To use comments starting with `!', set this to the string \"!\".
586 set this to the string \"!\". 699 `fortran-do-indent'
587 `fortran-do-indent' 700 Extra indentation within DO blocks (default 3).
588 Extra indentation within do blocks. (default 3) 701 `fortran-if-indent'
589 `fortran-if-indent' 702 Extra indentation within IF blocks (default 3).
590 Extra indentation within if blocks. (default 3) 703 `fortran-structure-indent'
591 `fortran-structure-indent' 704 Extra indentation within STRUCTURE, UNION, MAP and INTERFACE blocks.
592 Extra indentation within structure, union, map and interface blocks. 705 (default 3)
593 (default 3) 706 `fortran-continuation-indent'
594 `fortran-continuation-indent' 707 Extra indentation applied to continuation statements (default 5).
595 Extra indentation applied to continuation statements. (default 5) 708 `fortran-comment-line-extra-indent'
596 `fortran-comment-line-extra-indent' 709 Amount of extra indentation for text in full-line comments (default 0).
597 Amount of extra indentation for text within full-line comments. (default 0) 710 `fortran-comment-indent-style'
598 `fortran-comment-indent-style' 711 How to indent the text in full-line comments. Allowed values are:
599 nil means don't change indentation of text in full-line comments, 712 nil don't change the indentation
600 fixed means indent that text at `fortran-comment-line-extra-indent' beyond 713 fixed indent to `fortran-comment-line-extra-indent' beyond the
601 the value of `fortran-minimum-statement-indent-fixed' (for fixed 714 value of either
602 format continuation style) or `fortran-minimum-statement-indent-tab' 715 `fortran-minimum-statement-indent-fixed' (fixed format) or
603 (for TAB format continuation style). 716 `fortran-minimum-statement-indent-tab' (TAB format),
604 relative means indent at `fortran-comment-line-extra-indent' beyond the 717 depending on the continuation format in use.
718 relative indent to `fortran-comment-line-extra-indent' beyond the
605 indentation for a line of code. 719 indentation for a line of code.
606 (default 'fixed) 720 (default 'fixed)
607 `fortran-comment-indent-char' 721 `fortran-comment-indent-char'
608 Single-character string to be inserted instead of space for 722 Single-character string to be inserted instead of space for
609 full-line comment indentation. (default \" \") 723 full-line comment indentation (default \" \").
610 `fortran-minimum-statement-indent-fixed' 724 `fortran-minimum-statement-indent-fixed'
611 Minimum indentation for Fortran statements in fixed format mode. (def.6) 725 Minimum indentation for statements in fixed format mode (default 6).
612 `fortran-minimum-statement-indent-tab' 726 `fortran-minimum-statement-indent-tab'
613 Minimum indentation for Fortran statements in TAB format mode. (default 9) 727 Minimum indentation for statements in TAB format mode (default 9).
614 `fortran-line-number-indent' 728 `fortran-line-number-indent'
615 Maximum indentation for line numbers. A line number will get 729 Maximum indentation for line numbers (default 1). A line number will
616 less than this much indentation if necessary to avoid reaching 730 get less than this much indentation if necessary to avoid reaching
617 column 5. (default 1) 731 column 5.
618 `fortran-check-all-num-for-matching-do' 732 `fortran-check-all-num-for-matching-do'
619 Non-nil causes all numbered lines to be treated as possible \"continue\" 733 Non-nil causes all numbered lines to be treated as possible \"continue\"
620 statements. (default nil) 734 statements (default nil).
621 `fortran-blink-matching-if' 735 `fortran-blink-matching-if'
622 Non-nil causes \\[fortran-indent-line] on an ENDIF statement to blink on 736 Non-nil causes \\[fortran-indent-line] on an ENDIF (or ENDDO) statement
623 matching IF. Also, from an ENDDO statement, blink on matching DO [WHILE] 737 to blink on the matching IF (or DO [WHILE]). (default nil)
624 statement. (default nil) 738 `fortran-continuation-string'
625 `fortran-continuation-string' 739 Single-character string to be inserted in column 5 of a continuation
626 Single-character string to be inserted in column 5 of a continuation 740 line (default \"$\").
627 line. (default \"$\") 741 `fortran-comment-region'
628 `fortran-comment-region' 742 String inserted by \\[fortran-comment-region] at start of each line in
629 String inserted by \\[fortran-comment-region] at start of each line in 743 the region (default \"c$$$\").
630 region. (default \"c$$$\") 744 `fortran-electric-line-number'
631 `fortran-electric-line-number' 745 Non-nil causes line number digits to be moved to the correct column
632 Non-nil causes line number digits to be moved to the correct column 746 as typed (default t).
633 as typed. (default t) 747 `fortran-break-before-delimiters'
634 `fortran-break-before-delimiters' 748 Non-nil causes lines to be broken before delimiters (default t).
635 Non-nil causes lines to be broken before delimiters.
636 (default t)
637 749
638 Turning on Fortran mode calls the value of the variable `fortran-mode-hook' 750 Turning on Fortran mode calls the value of the variable `fortran-mode-hook'
639 with no args, if that value is non-nil." 751 with no args, if that value is non-nil."
640 (interactive) 752 (interactive)
641 (kill-all-local-variables) 753 (kill-all-local-variables)
642 (setq local-abbrev-table fortran-mode-abbrev-table) 754 (setq major-mode 'fortran-mode
755 mode-name "Fortran"
756 local-abbrev-table fortran-mode-abbrev-table)
643 (set-syntax-table fortran-mode-syntax-table) 757 (set-syntax-table fortran-mode-syntax-table)
644 ;; Font Lock mode support. 758 (use-local-map fortran-mode-map)
645 (make-local-variable 'font-lock-defaults) 759 (set (make-local-variable 'indent-line-function) 'fortran-indent-line)
646 (setq font-lock-defaults '((fortran-font-lock-keywords 760 (set (make-local-variable 'indent-region-function)
647 fortran-font-lock-keywords-1 761 (lambda (start end)
648 fortran-font-lock-keywords-2 762 (let (fortran-blink-matching-if ; avoid blinking delay
649 fortran-font-lock-keywords-3) 763 indent-region-function)
650 nil t ((?/ . "$/") ("_$" . "w")) 764 (indent-region start end nil))))
651 fortran-beginning-of-subprogram)) 765 (set (make-local-variable 'require-final-newline) mode-require-final-newline)
652 (set (make-local-variable 'font-lock-syntactic-keywords) 766 ;; The syntax tables don't understand the column-0 comment-markers.
653 fortran-font-lock-syntactic-keywords) 767 (set (make-local-variable 'comment-use-syntax) nil)
654 (make-local-variable 'fortran-break-before-delimiters) 768 (set (make-local-variable 'comment-padding) "$$$")
655 (setq fortran-break-before-delimiters t) 769 (set (make-local-variable 'comment-start) fortran-comment-line-start)
656 (make-local-variable 'indent-line-function)
657 (setq indent-line-function 'fortran-indent-line)
658 (make-local-variable 'comment-indent-function)
659 (setq comment-indent-function 'fortran-comment-indent)
660 (set (make-local-variable 'comment-start-skip) 770 (set (make-local-variable 'comment-start-skip)
661 ;; We can't reuse `fortran-comment-line-start-skip' directly because 771 ;; We can't reuse `fortran-comment-line-start-skip' directly because
662 ;; it contains backrefs whereas we need submatch-1 to end at the 772 ;; it contains backrefs whereas we need submatch-1 to end at the
663 ;; beginning of the comment delimiter. 773 ;; beginning of the comment delimiter.
664 ;; (concat "\\(\\)\\(![ \t]*\\|" fortran-comment-line-start-skip "\\)") 774 ;; (concat "\\(\\)\\(![ \t]*\\|" fortran-comment-line-start-skip "\\)")
665 "\\(\\)\\(?:^[CcDd*]\\|!\\)\\(?:\\([^ \t\n]\\)\\2+\\)?[ \t]*") 775 "\\(\\)\\(?:^[CcDd*]\\|!\\)\\(?:\\([^ \t\n]\\)\\2+\\)?[ \t]*")
666 (set (make-local-variable 'comment-padding) "$$$") 776 (set (make-local-variable 'comment-indent-function) 'fortran-comment-indent)
667 (set (make-local-variable 'comment-start) fortran-comment-line-start) 777 (set (make-local-variable 'abbrev-all-caps) t)
668 ;; The syntax tables don't understand the column-0 comment-markers. 778 (set (make-local-variable 'normal-auto-fill-function) 'fortran-auto-fill)
669 (set (make-local-variable 'comment-use-syntax) nil) 779 (set (make-local-variable 'indent-tabs-mode) (fortran-analyze-file-format))
670 (make-local-variable 'require-final-newline) 780 (setq mode-line-process '(indent-tabs-mode fortran-tab-mode-string))
671 (setq require-final-newline t)
672 (make-local-variable 'abbrev-all-caps)
673 (setq abbrev-all-caps t)
674 (make-local-variable 'indent-tabs-mode)
675 (setq indent-tabs-mode nil)
676 ;;;(setq abbrev-mode t) ; ?? (abbrev-mode 1) instead??
677 (set (make-local-variable 'fill-column) 72) 781 (set (make-local-variable 'fill-column) 72)
678 (use-local-map fortran-mode-map)
679 (setq mode-name "Fortran")
680 (setq major-mode 'fortran-mode)
681 (make-local-variable 'fortran-comment-line-extra-indent)
682 (make-local-variable 'fortran-minimum-statement-indent-fixed)
683 (make-local-variable 'fortran-minimum-statement-indent-tab)
684 (make-local-variable 'fortran-column-ruler-fixed)
685 (make-local-variable 'fortran-column-ruler-tab)
686 (setq fortran-tab-mode-string " TAB-format")
687 (setq indent-tabs-mode (fortran-analyze-file-format))
688 (setq imenu-case-fold-search t)
689 (setq imenu-generic-expression fortran-imenu-generic-expression)
690 (setq imenu-syntax-alist '(("_$" . "w")))
691 (set (make-local-variable 'fill-paragraph-function) 'fortran-fill-paragraph) 782 (set (make-local-variable 'fill-paragraph-function) 'fortran-fill-paragraph)
692 (set (make-local-variable 'normal-auto-fill-function) 'fortran-auto-fill) 783 (set (make-local-variable 'font-lock-defaults)
693 (set (make-local-variable 'indent-line-function) 'fortran-indent-line) 784 '((fortran-font-lock-keywords
694 (set (make-local-variable 'indent-region-function) 785 fortran-font-lock-keywords-1
695 (lambda (start end) 786 fortran-font-lock-keywords-2
696 (let (fortran-blink-matching-if ; avoid blinking delay 787 fortran-font-lock-keywords-3
697 indent-region-function) 788 fortran-font-lock-keywords-4)
698 (indent-region start end nil)))) 789 nil t ((?/ . "$/") ("_$" . "w"))
790 fortran-beginning-of-subprogram))
791 (set (make-local-variable 'font-lock-syntactic-keywords)
792 fortran-font-lock-syntactic-keywords)
793 (set (make-local-variable 'imenu-case-fold-search) t)
794 (set (make-local-variable 'imenu-generic-expression)
795 fortran-imenu-generic-expression)
796 (set (make-local-variable 'imenu-syntax-alist) '(("_$" . "w")))
699 (set (make-local-variable 'beginning-of-defun-function) 797 (set (make-local-variable 'beginning-of-defun-function)
700 #'fortran-beginning-of-subprogram) 798 #'fortran-beginning-of-subprogram)
701 (set (make-local-variable 'end-of-defun-function) 799 (set (make-local-variable 'end-of-defun-function)
702 #'fortran-end-of-subprogram) 800 #'fortran-end-of-subprogram)
703 (set (make-local-variable 'add-log-current-defun-function) 801 (set (make-local-variable 'add-log-current-defun-function)
704 #'fortran-current-defun) 802 #'fortran-current-defun)
705 (set (make-local-variable 'dabbrev-case-fold-search) 'case-fold-search) 803 (set (make-local-variable 'dabbrev-case-fold-search) 'case-fold-search)
706 (run-hooks 'fortran-mode-hook)) 804 (set (make-local-variable 'gud-find-expr-function) 'fortran-gud-find-expr)
805 (run-mode-hooks 'fortran-mode-hook))
806
707 807
808 (defun fortran-gud-find-expr ()
809 ;; Consider \n as punctuation (end of expression).
810 (with-syntax-table fortran-gud-syntax-table
811 (gud-find-c-expr)))
812
708 (defsubst fortran-comment-indent () 813 (defsubst fortran-comment-indent ()
709 (save-excursion 814 "Return the indentation appropriate for the current comment line.
710 (if (looking-at fortran-comment-line-start-skip) 0 815 This is 0 for a line matching `fortran-comment-line-start-skip', else
816 the value of `comment-column' (leaving at least one space after code)."
817 (if (looking-at fortran-comment-line-start-skip) 0
818 (save-excursion
711 (skip-chars-backward " \t") 819 (skip-chars-backward " \t")
712 (max (+ 1 (current-column)) 820 (max (1+ (current-column)) comment-column))))
713 comment-column))))
714 821
715 (defun fortran-indent-comment () 822 (defun fortran-indent-comment ()
716 "Align or create comment on current line. 823 "Align or create comment on current line.
717 Existing comments of all types are recognized and aligned. 824 Existing comments of all types are recognized and aligned.
718 If the line has no comment, a side-by-side comment is inserted and aligned 825 If the line has no comment, a side-by-side comment is inserted and aligned,
719 if the value of `comment-start' is not nil and allows such comments. 826 if the value of `comment-start' is not nil and allows such comments.
720 Otherwise, a separate-line comment is inserted, on this line 827 Otherwise, a separate-line comment is inserted, on this line
721 or on a new line inserted before this line if this line is not blank." 828 or on a new line inserted before this line if this line is not blank."
722 (interactive) 829 (interactive "*")
723 (beginning-of-line) 830 (beginning-of-line)
724 ;; Recognize existing comments of either kind. 831 ;; Recognize existing comments of either kind.
725 (cond ((fortran-find-comment-start-skip 'all) 832 (cond ((fortran-find-comment-start-skip 'all)
726 (goto-char (match-beginning 0)) 833 (goto-char (match-beginning 0))
727 (if (bolp) 834 (if (bolp)
728 (fortran-indent-line) 835 (fortran-indent-line)
729 (if (not (= (current-column) 836 (unless (= (current-column) (fortran-comment-indent))
730 (fortran-comment-indent))) 837 (delete-horizontal-space)
731 (progn (delete-horizontal-space) 838 (indent-to (fortran-comment-indent)))))
732 (indent-to (fortran-comment-indent))))))
733 ;; No existing comment. 839 ;; No existing comment.
734 ;; If side-by-side comments are defined, insert one, 840 ;; If side-by-side comments are defined, insert one,
735 ;; unless line is now blank. 841 ;; unless line is now blank.
736 ((and comment-start (not (looking-at "[ \t]*$")) 842 ((and comment-start (not (looking-at "[ \t]*$"))
737 (string-match comment-start-skip (concat " " comment-start))) 843 (string-match comment-start-skip (concat " " comment-start)))
751 (aref fortran-comment-indent-char 0) 857 (aref fortran-comment-indent-char 0)
752 fortran-comment-indent-char) 858 fortran-comment-indent-char)
753 (- (fortran-calculate-indent) (current-column)))))) 859 (- (fortran-calculate-indent) (current-column))))))
754 860
755 (defun fortran-comment-region (beg-region end-region arg) 861 (defun fortran-comment-region (beg-region end-region arg)
756 "Comments every line in the region. 862 "Comment every line in the region.
757 Puts `fortran-comment-region' at the beginning of every line in the region. 863 Inserts the string variable `fortran-comment-region' at the beginning of
758 BEG-REGION and END-REGION are args which specify the region boundaries. 864 every line in the region.
865 BEG-REGION and END-REGION specify the region boundaries.
759 With non-nil ARG, uncomments the region." 866 With non-nil ARG, uncomments the region."
760 (interactive "*r\nP") 867 (interactive "*r\nP")
761 (let ((end-region-mark (copy-marker end-region)) 868 (let ((end-region-mark (copy-marker end-region))
762 (save-point (point-marker))) 869 (save-point (point-marker)))
763 (goto-char beg-region) 870 (goto-char beg-region)
764 (beginning-of-line) 871 (beginning-of-line)
765 (if (not arg) ;comment the region 872 (if arg
766 (progn (insert fortran-comment-region) 873 (let ((com (regexp-quote fortran-comment-region))) ; uncomment
767 (while (and (= (forward-line 1) 0) 874 (if (looking-at com)
768 (< (point) end-region-mark)) 875 (delete-region (point) (match-end 0)))
769 (insert fortran-comment-region))) 876 (while (and (zerop (forward-line 1))
770 (let ((com (regexp-quote fortran-comment-region))) ;uncomment the region 877 (< (point) end-region-mark))
771 (if (looking-at com) 878 (if (looking-at com)
772 (delete-region (point) (match-end 0))) 879 (delete-region (point) (match-end 0)))))
773 (while (and (= (forward-line 1) 0) 880 (insert fortran-comment-region) ; comment
774 (< (point) end-region-mark)) 881 (while (and (zerop (forward-line 1))
775 (if (looking-at com) 882 (< (point) end-region-mark))
776 (delete-region (point) (match-end 0)))))) 883 (insert fortran-comment-region)))
777 (goto-char save-point) 884 (goto-char save-point)
778 (set-marker end-region-mark nil) 885 (set-marker end-region-mark nil)
779 (set-marker save-point nil))) 886 (set-marker save-point nil)))
887
780 888
781 (defun fortran-abbrev-start () 889 (defun fortran-abbrev-start ()
782 "Typing ;\\[help-command] or ;? lists all the Fortran abbrevs. 890 "Typing ;\\[help-command] or ;? lists all the Fortran abbrevs.
783 Any other key combination is executed normally." 891 Any other key combination is executed normally."
784 (interactive) 892 (interactive "*")
785 (let (c) 893 (insert last-command-char)
786 (insert last-command-char) 894 (let (char event)
787 (if (or (eq (setq c (read-event)) ??) ;insert char if not equal to `?' 895 (if (fboundp 'next-command-event) ; XEmacs
788 (eq c help-char)) 896 (setq event (next-command-event)
897 char (event-to-character event))
898 (setq event (read-event)
899 char event))
900 ;; Insert char if not equal to `?', or if abbrev-mode is off.
901 (if (and abbrev-mode (or (eq char ??) (eq char help-char)))
789 (fortran-abbrev-help) 902 (fortran-abbrev-help)
790 (setq unread-command-events (list c))))) 903 (setq unread-command-events (list event)))))
791 904
792 (defun fortran-abbrev-help () 905 (defun fortran-abbrev-help ()
793 "List the currently defined abbrevs in Fortran mode." 906 "List the currently defined abbrevs in Fortran mode."
794 (interactive) 907 (interactive)
795 (message "Listing abbrev table...") 908 (message "Listing abbrev table...")
796 (display-buffer (fortran-prepare-abbrev-list-buffer)) 909 (display-buffer (fortran-prepare-abbrev-list-buffer))
797 (message "Listing abbrev table...done")) 910 (message "Listing abbrev table...done"))
798 911
799 (defun fortran-prepare-abbrev-list-buffer () 912 (defun fortran-prepare-abbrev-list-buffer ()
913 "Create a buffer listing the Fortran mode abbreviations."
800 (save-excursion 914 (save-excursion
801 (set-buffer (get-buffer-create "*Abbrevs*")) 915 (set-buffer (get-buffer-create "*Abbrevs*"))
802 (erase-buffer) 916 (erase-buffer)
803 (insert-abbrev-table-description 'fortran-mode-abbrev-table t) 917 (insert-abbrev-table-description 'fortran-mode-abbrev-table t)
804 (goto-char (point-min)) 918 (goto-char (point-min))
806 (edit-abbrevs-mode)) 920 (edit-abbrevs-mode))
807 (get-buffer-create "*Abbrevs*")) 921 (get-buffer-create "*Abbrevs*"))
808 922
809 (defun fortran-column-ruler () 923 (defun fortran-column-ruler ()
810 "Insert a column ruler momentarily above current line, till next keystroke. 924 "Insert a column ruler momentarily above current line, till next keystroke.
811 The ruler is defined by the value of `fortran-column-ruler-fixed' when in fixed 925 The ruler is defined by the value of `fortran-column-ruler-fixed' in fixed
812 format mode, and `fortran-column-ruler-tab' when in TAB format mode. 926 format mode, and `fortran-column-ruler-tab' in TAB format mode.
813 The key typed is executed unless it is SPC." 927 The next key typed is executed unless it is SPC."
814 (interactive) 928 (interactive)
815 (momentary-string-display 929 (momentary-string-display
816 (if indent-tabs-mode 930 (if indent-tabs-mode
817 fortran-column-ruler-tab 931 fortran-column-ruler-tab
818 fortran-column-ruler-fixed) 932 fortran-column-ruler-fixed)
859 (setq unread-command-events (list char)))))) 973 (setq unread-command-events (list char))))))
860 (fortran-window-create))) 974 (fortran-window-create)))
861 975
862 (defun fortran-split-line () 976 (defun fortran-split-line ()
863 "Break line at point and insert continuation marker and alignment." 977 "Break line at point and insert continuation marker and alignment."
864 (interactive) 978 (interactive "*")
865 (delete-horizontal-space) 979 (delete-horizontal-space)
866 (if (save-excursion 980 (if (save-excursion
867 (let ((pos (point))) 981 (let ((pos (point)))
868 (beginning-of-line) 982 (beginning-of-line)
869 (and (fortran-find-comment-start-skip 'all) 983 (and (fortran-find-comment-start-skip 'all)
870 (< (match-beginning 0) pos)))) 984 (< (match-beginning 0) pos))))
871 (insert ?\n (match-string 0)) 985 (insert ?\n (match-string 0))
872 (if indent-tabs-mode 986 (if indent-tabs-mode
873 (insert ?\n ?\t (fortran-numerical-continuation-char)) 987 (insert ?\n ?\t (fortran-numerical-continuation-char))
874 (insert "\n " fortran-continuation-string))) ; Space after \n important 988 (insert "\n " fortran-continuation-string))) ; space after \n important
875 (fortran-indent-line)) ; when the cont string is C, c or *. 989 (fortran-indent-line)) ; when cont string is C, c or *
876 990
877 (defun fortran-remove-continuation () 991 (defun fortran-remove-continuation ()
878 (if (looking-at "\\( [^ 0\n]\\|\t[1-9]\\|&\\)") 992 "Delete any Fortran continuation characters at point.
879 (progn (replace-match "") 993 Returns t if anything actually deleted."
880 (delete-indentation) 994 (when (looking-at "\\( \\{5\\}[^ 0\n]\\|\t[1-9]\\|&\\)")
881 t))) 995 (replace-match "")
996 (delete-indentation)
997 t))
882 998
883 (defun fortran-join-line (arg) 999 (defun fortran-join-line (arg)
884 "Join current line to the previous one and re-indent. 1000 "Join current line to the previous one and re-indent.
885 With a prefix argument, repeat this operation that many times. 1001 With a prefix argument, repeat this operation that many times.
886 If the prefix argument ARG is negative, join the next -ARG lines. 1002 If the prefix argument ARG is negative, join the next -ARG lines.
897 (setq arg (1- arg))) 1013 (setq arg (1- arg)))
898 (fortran-indent-line))) 1014 (fortran-indent-line)))
899 1015
900 (defun fortran-numerical-continuation-char () 1016 (defun fortran-numerical-continuation-char ()
901 "Return a digit for tab-digit style of continuation lines. 1017 "Return a digit for tab-digit style of continuation lines.
902 If, previous line is a tab-digit continuation line, returns that digit 1018 If previous line is a tab-digit continuation line, return that digit
903 plus one. Otherwise return 1. Zero not allowed." 1019 plus one, otherwise return 1. Zero not allowed."
904 (save-excursion 1020 (save-excursion
905 (forward-line -1) 1021 (forward-line -1)
906 (if (looking-at "\t[1-9]") 1022 (if (looking-at "\t[1-9]")
907 (+ ?1 (% (- (char-after (+ (point) 1)) ?0) 9)) 1023 (+ ?1 (% (- (char-after (1+ (point))) ?0) 9))
908 ?1))) 1024 ?1)))
909 1025
910 (put 'fortran-electric-line-number 'delete-selection t) 1026 (put 'fortran-electric-line-number 'delete-selection t)
911 (defun fortran-electric-line-number (arg) 1027 (defun fortran-electric-line-number (arg)
912 "Self insert, but if part of a Fortran line number indent it automatically. 1028 "Self insert, but if part of a Fortran line number indent it automatically.
913 Auto-indent does not happen if a numeric ARG is used." 1029 Auto-indent does not happen if a numeric ARG is used."
914 (interactive "P") 1030 (interactive "*P")
915 (if (or arg (not fortran-electric-line-number)) 1031 (if (or arg (not fortran-electric-line-number))
916 (if arg 1032 (if arg
917 (self-insert-command (prefix-numeric-value arg)) 1033 (self-insert-command (prefix-numeric-value arg))
918 (self-insert-command 1)) 1034 (self-insert-command 1))
919 (if (or (and (= 5 (current-column)) 1035 (if (or (and (= 5 (current-column))
920 (save-excursion 1036 (save-excursion
921 (beginning-of-line) 1037 (beginning-of-line)
922 (looking-at " \\{5\\}"))) ;In col 5 with only spaces to left. 1038 ;; In col 5 with only spaces to the left.
1039 (looking-at " \\{5\\}")))
923 (and (= (if indent-tabs-mode 1040 (and (= (if indent-tabs-mode
924 fortran-minimum-statement-indent-tab 1041 fortran-minimum-statement-indent-tab
925 fortran-minimum-statement-indent-fixed) (current-column)) 1042 fortran-minimum-statement-indent-fixed) (current-column))
926 (eq ?\t (char-after (line-beginning-position))) ;In col 8 1043 ;; In col 8 with a single tab to the left.
927 ; with a single tab to the left. 1044 (eq ?\t (char-after (line-beginning-position)))
928 (not (or (eq last-command 'fortran-indent-line) 1045 (not (or (eq last-command 'fortran-indent-line)
929 (eq last-command 1046 (eq last-command
930 'fortran-indent-new-line)))) 1047 'fortran-indent-new-line))))
931 (save-excursion 1048 (save-excursion
932 (re-search-backward "[^ \t0-9]" 1049 (re-search-backward "[^ \t0-9]"
933 (line-beginning-position) 1050 (line-beginning-position)
934 t)) ;not a line number 1051 t)) ; not a line number
935 (looking-at "[0-9]")) ;within a line number 1052 (looking-at "[0-9]")) ; within a line number
936 (self-insert-command (prefix-numeric-value arg)) 1053 (self-insert-command (prefix-numeric-value arg))
937 (skip-chars-backward " \t") 1054 (skip-chars-backward " \t")
938 (insert last-command-char) 1055 (insert last-command-char)
939 (fortran-indent-line)))) 1056 (fortran-indent-line))))
1057
940 1058
941 (defvar fortran-end-prog-re1
942 "end\
943 \\([ \t]*\\(program\\|subroutine\\|function\\|block[ \t]*data\\)\\>\
944 \\([ \t]*\\(\\sw\\|\\s_\\)+\\)?\\)?")
945 (defvar fortran-end-prog-re
946 (concat "^[ \t0-9]*" fortran-end-prog-re1)
947 "Regexp possibly marking subprogram end.")
948
949 (defun fortran-check-end-prog-re () 1059 (defun fortran-check-end-prog-re ()
950 "Check a preliminary match against `fortran-end-prog-re'." 1060 "Check a preliminary match against `fortran-end-prog-re'."
951 ;; Having got a possible match for the subprogram end, we need a 1061 ;; Having got a possible match for the subprogram end, we need a
952 ;; match of whitespace, avoiding possible column 73+ stuff. 1062 ;; match of whitespace, avoiding possible column 73+ stuff.
953 (save-match-data 1063 (save-match-data
1002 (not (looking-at fortran-directive-re)) 1112 (not (looking-at fortran-directive-re))
1003 (or (looking-at 1113 (or (looking-at
1004 (concat "[ \t]*" 1114 (concat "[ \t]*"
1005 (regexp-quote fortran-continuation-string))) 1115 (regexp-quote fortran-continuation-string)))
1006 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")))) 1116 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]"))))
1007 (while (and (setq not-first-statement (= (forward-line -1) 0)) 1117 (while (and (setq not-first-statement (zerop (forward-line -1)))
1008 (or (looking-at fortran-comment-line-start-skip) 1118 (or (looking-at fortran-comment-line-start-skip)
1009 (looking-at fortran-directive-re) 1119 (looking-at fortran-directive-re)
1120 (looking-at
1121 (concat "[ \t]*"
1122 (regexp-quote fortran-continuation-string)))
1010 (looking-at "[ \t]*$\\| \\{5\\}[^ 0\n]\\|\t[1-9]") 1123 (looking-at "[ \t]*$\\| \\{5\\}[^ 0\n]\\|\t[1-9]")
1011 (looking-at (concat "[ \t]*" comment-start-skip))))) 1124 (looking-at (concat "[ \t]*" comment-start-skip)))))
1012 (cond ((and continue-test 1125 (cond ((and continue-test
1013 (not not-first-statement)) 1126 (not not-first-statement))
1014 (message "Incomplete continuation statement.")) 1127 (message "Incomplete continuation statement."))
1024 Directive lines are treated as comments." 1137 Directive lines are treated as comments."
1025 (interactive) 1138 (interactive)
1026 (let (not-last-statement) 1139 (let (not-last-statement)
1027 (beginning-of-line) 1140 (beginning-of-line)
1028 (while (and (setq not-last-statement 1141 (while (and (setq not-last-statement
1029 (and (= (forward-line 1) 0) 1142 (and (zerop (forward-line 1))
1030 (not (eobp)))) 1143 (not (eobp))))
1031 (or (looking-at fortran-comment-line-start-skip) 1144 (or (looking-at fortran-comment-line-start-skip)
1032 (looking-at fortran-directive-re) 1145 (looking-at fortran-directive-re)
1033 (looking-at "[ \t]*$\\| [^ 0\n]\\|\t[1-9]") 1146 (looking-at "[ \t]*$\\| [^ 0\n]\\|\t[1-9]")
1034 (looking-at (concat "[ \t]*" comment-start-skip))))) 1147 (looking-at (concat "[ \t]*" comment-start-skip)))))
1035 (if (not not-last-statement) 1148 (if (not not-last-statement)
1036 'last-statement))) 1149 'last-statement)))
1150
1151 (defun fortran-looking-at-if-then ()
1152 "Return non-nil if at the start of a line with an IF ... THEN statement."
1153 ;; cf f90-looking-at-if-then.
1154 (let ((p (point))
1155 (i (fortran-beginning-if)))
1156 (if i
1157 (save-excursion
1158 (goto-char i)
1159 (beginning-of-line)
1160 (= (point) p)))))
1161
1162 ;; Used in hs-special-modes-alist.
1163 (defun fortran-end-of-block (&optional num)
1164 "Move point forward to the end of the current code block.
1165 With optional argument NUM, go forward that many balanced blocks.
1166 If NUM is negative, go backward to the start of a block. Does
1167 not check for consistency of block types. Interactively, pushes
1168 mark before moving point."
1169 (interactive "p")
1170 (if (interactive-p) (push-mark (point) t))
1171 (and num (< num 0) (fortran-beginning-of-block (- num)))
1172 (let ((case-fold-search t)
1173 (count (or num 1)))
1174 (end-of-line)
1175 (while (and (> count 0)
1176 (re-search-forward
1177 (concat "\\(" fortran-blocks-re
1178 (if fortran-check-all-num-for-matching-do
1179 "\\|^[ \t]*[0-9]+" "")
1180 "\\|continue\\|end\\)\\>")
1181 nil 'move))
1182 (beginning-of-line)
1183 (if (if (looking-at (concat "^[0-9 \t]*" fortran-if-start-re))
1184 (fortran-looking-at-if-then)
1185 (looking-at fortran-start-block-re))
1186 (setq count (1+ count))
1187 (if (or (looking-at fortran-end-block-re)
1188 (and (or (looking-at "^[0-9 \t]*continue")
1189 (and fortran-check-all-num-for-matching-do
1190 (looking-at "[ \t]*[0-9]+")))
1191 (fortran-check-for-matching-do)))
1192 (setq count (1- count))))
1193 (end-of-line))
1194 (if (> count 0) (error "Missing block end"))))
1195
1196 (defun fortran-beginning-of-block (&optional num)
1197 "Move point backwards to the start of the current code block.
1198 With optional argument NUM, go backward that many balanced
1199 blocks. If NUM is negative, go forward to the end of a block.
1200 Does not check for consistency of block types. Interactively,
1201 pushes mark before moving point."
1202 (interactive "p")
1203 (if (interactive-p) (push-mark (point) t))
1204 (and num (< num 0) (fortran-end-of-block (- num)))
1205 (let ((case-fold-search t)
1206 (count (or num 1)))
1207 (beginning-of-line)
1208 (while (and (> count 0)
1209 (re-search-backward
1210 (concat "\\(" fortran-blocks-re
1211 (if fortran-check-all-num-for-matching-do
1212 "\\|^[ \t]*[0-9]+" "")
1213 "\\|continue\\|end\\)\\>")
1214 nil 'move))
1215 (beginning-of-line)
1216 (if (if (looking-at (concat "^[0-9 \t]*" fortran-if-start-re))
1217 (fortran-looking-at-if-then)
1218 (looking-at fortran-start-block-re))
1219 (setq count (1- count))
1220 (if (or (looking-at fortran-end-block-re)
1221 (and (or (looking-at "^[0-9 \t]*continue")
1222 (and fortran-check-all-num-for-matching-do
1223 (looking-at "[ \t]*[0-9]+")))
1224 (fortran-check-for-matching-do)))
1225 (setq count (1+ count)))))
1226 ;; Includes an un-named main program block.
1227 (if (> count 0) (error "Missing block start"))))
1228
1037 1229
1038 (defun fortran-blink-match (regex keyword find-begin) 1230 (defun fortran-blink-match (regex keyword find-begin)
1039 "From a line matching REGEX, blink matching KEYWORD statement line. 1231 "From a line matching REGEX, blink matching KEYWORD statement line.
1040 Use function FIND-BEGIN to match it." 1232 Use function FIND-BEGIN to match it."
1041 (let ((top-of-window (window-start)) 1233 (let ((top-of-window (window-start))
1042 (end-point (point)) 1234 (end-point (point))
1043 (case-fold-search t) 1235 (case-fold-search t)
1044 matching 1236 matching
1045 message) 1237 message)
1046 (if (save-excursion 1238 (when (save-excursion
1047 (beginning-of-line) 1239 (beginning-of-line)
1048 (skip-chars-forward " \t0-9") 1240 (skip-chars-forward " \t0-9")
1049 (looking-at regex)) 1241 (looking-at regex))
1050 (progn 1242 (if (not (setq matching (funcall find-begin)))
1051 (if (not (setq matching (funcall find-begin))) 1243 (setq message (concat "No matching " keyword "."))
1052 (setq message (concat "No matching " keyword ".")) 1244 (if (< matching top-of-window)
1053 (if (< matching top-of-window) 1245 (save-excursion
1054 (save-excursion 1246 (goto-char matching)
1055 (goto-char matching) 1247 (beginning-of-line)
1056 (beginning-of-line) 1248 (setq message
1057 (setq message 1249 (concat "Matches "
1058 (concat "Matches " 1250 (buffer-substring (point)
1059 (buffer-substring (point) 1251 (line-end-position)))))))
1060 (line-end-position))))))) 1252 (if message
1061 (if message 1253 (message "%s" message)
1062 (message "%s" message) 1254 (goto-char matching)
1063 (goto-char matching) 1255 (sit-for blink-matching-delay)
1064 (sit-for 1) 1256 (goto-char end-point)))))
1065 (goto-char end-point))))))
1066 1257
1067 (defun fortran-blink-matching-if () 1258 (defun fortran-blink-matching-if ()
1068 "From an ENDIF or ELSE statement, blink the matching IF statement." 1259 "From an ENDIF or ELSE statement, blink the matching IF statement."
1069 (fortran-blink-match "e\\(nd[ \t]*if\\|lse\\([ \t]*if\\)?\\)\\b" 1260 (fortran-blink-match "e\\(nd[ \t]*if\\|lse\\([ \t]*if\\)?\\)\\b"
1070 "if" #'fortran-beginning-if)) 1261 "if" #'fortran-beginning-if))
1095 ;; Sitting on one. 1286 ;; Sitting on one.
1096 (match-beginning 0) 1287 (match-beginning 0)
1097 ;; Search for one. 1288 ;; Search for one.
1098 (save-excursion 1289 (save-excursion
1099 (let ((count 1)) 1290 (let ((count 1))
1100 (while (and (not (= count 0)) 1291 (while (and (not (zerop count))
1101 (not (eq (fortran-next-statement) 'last-statement)) 1292 (not (eq (fortran-next-statement) 'last-statement))
1102 ;; Keep local to subprogram 1293 ;; Keep local to subprogram.
1103 (not (and (looking-at fortran-end-prog-re) 1294 (not (and (looking-at fortran-end-prog-re)
1104 (fortran-check-end-prog-re)))) 1295 (fortran-check-end-prog-re))))
1105 (skip-chars-forward " \t0-9") 1296 (skip-chars-forward " \t0-9")
1106 (cond ((looking-at "end[ \t]*do\\b") 1297 (cond ((looking-at "end[ \t]*do\\b")
1107 (setq count (1- count))) 1298 (setq count (1- count)))
1108 ((looking-at 1299 ((looking-at
1109 "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]") 1300 "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]")
1110 (setq count (+ count 1))))) 1301 (setq count (1+ count)))))
1111 (and (= count 0) 1302 (and (zerop count)
1112 ;; All pairs accounted for. 1303 ;; All pairs accounted for.
1113 (point))))))) 1304 (point)))))))
1114 1305
1115 (defun fortran-beginning-do () 1306 (defun fortran-beginning-do ()
1116 "Search backwards for first unmatched DO [WHILE]. 1307 "Search backwards for first unmatched DO [WHILE].
1124 ;; Sitting on one. 1315 ;; Sitting on one.
1125 (match-beginning 0) 1316 (match-beginning 0)
1126 ;; Search for one. 1317 ;; Search for one.
1127 (save-excursion 1318 (save-excursion
1128 (let ((count 1)) 1319 (let ((count 1))
1129 (while (and (not (= count 0)) 1320 (while (and (not (zerop count))
1130 (not (eq (fortran-previous-statement) 'first-statement)) 1321 (not (eq (fortran-previous-statement) 'first-statement))
1131 ;; Keep local to subprogram 1322 ;; Keep local to subprogram.
1132 (not (and (looking-at fortran-end-prog-re) 1323 (not (and (looking-at fortran-end-prog-re)
1133 (fortran-check-end-prog-re)))) 1324 (fortran-check-end-prog-re))))
1134 (skip-chars-forward " \t0-9") 1325 (skip-chars-forward " \t0-9")
1135 (cond ((looking-at dostart-re) 1326 (cond ((looking-at dostart-re)
1136 (setq count (1- count))) 1327 (setq count (1- count)))
1137 ;; Note labelled loop ends not considered. 1328 ;; Note labelled loop ends not considered.
1138 ((looking-at "end[ \t]*do\\b") 1329 ((looking-at "end[ \t]*do\\b")
1139 (setq count (1+ count))))) 1330 (setq count (1+ count)))))
1140 (and (= count 0) 1331 (and (zerop count)
1141 ;; All pairs accounted for. 1332 ;; All pairs accounted for.
1142 (point))))))) 1333 (point)))))))
1143 1334
1144 (defun fortran-mark-if () 1335 (defun fortran-mark-if ()
1145 "Put mark at end of Fortran IF-ENDIF construct, point at beginning. 1336 "Put mark at end of Fortran IF-ENDIF construct, point at beginning.
1151 (message "No matching if.") 1342 (message "No matching if.")
1152 ;; Set mark, move point. 1343 ;; Set mark, move point.
1153 (goto-char endif-point) 1344 (goto-char endif-point)
1154 (push-mark) 1345 (push-mark)
1155 (goto-char if-point))))) 1346 (goto-char if-point)))))
1156
1157 (defvar fortran-if-start-re "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(")
1158 1347
1159 (defun fortran-end-if () 1348 (defun fortran-end-if ()
1160 "Search forwards for first unmatched ENDIF. 1349 "Search forwards for first unmatched ENDIF.
1161 Return point or nil." 1350 Return point or nil."
1162 (let ((case-fold-search t)) 1351 (let ((case-fold-search t))
1167 (match-beginning 0) 1356 (match-beginning 0)
1168 ;; Search for one. The point has been already been moved to first 1357 ;; Search for one. The point has been already been moved to first
1169 ;; letter on line but this should not cause troubles. 1358 ;; letter on line but this should not cause troubles.
1170 (save-excursion 1359 (save-excursion
1171 (let ((count 1)) 1360 (let ((count 1))
1172 (while (and (not (= count 0)) 1361 (while (and (not (zerop count))
1173 (not (eq (fortran-next-statement) 'last-statement)) 1362 (not (eq (fortran-next-statement) 'last-statement))
1174 ;; Keep local to subprogram. 1363 ;; Keep local to subprogram.
1175 (not (and (looking-at fortran-end-prog-re) 1364 (not (and (looking-at fortran-end-prog-re)
1176 (fortran-check-end-prog-re)))) 1365 (fortran-check-end-prog-re))))
1177 (skip-chars-forward " \t0-9") 1366 (skip-chars-forward " \t0-9")
1178 (cond ((looking-at "end[ \t]*if\\b") 1367 (cond ((looking-at "end[ \t]*if\\b")
1179 (setq count (- count 1))) 1368 (setq count (1- count)))
1180 ((looking-at fortran-if-start-re) 1369 ((looking-at fortran-if-start-re)
1181 (save-excursion 1370 (save-excursion
1182 (if (or 1371 (if (or
1183 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") 1372 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
1184 (let (then-test) ; Multi-line if-then. 1373 (let (then-test) ; multi-line if-then
1185 (while 1374 (while
1186 (and 1375 (and
1187 (= (forward-line 1) 0) 1376 (zerop (forward-line 1))
1188 ;; Search forward for then. 1377 ;; Search forward for then.
1189 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]") 1378 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")
1190 (not 1379 (not
1191 (setq then-test 1380 (setq then-test
1192 (looking-at 1381 (looking-at
1193 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) 1382 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
1194 then-test)) 1383 then-test))
1195 (setq count (+ count 1))))))) 1384 (setq count (1+ count)))))))
1196 (and (= count 0) 1385 (and (zerop count)
1197 ;; All pairs accounted for. 1386 ;; All pairs accounted for.
1198 (point))))))) 1387 (point)))))))
1199 1388
1200 (defun fortran-beginning-if () 1389 (defun fortran-beginning-if ()
1201 "Search backwards for first unmatched IF-THEN. 1390 "Search backwards for first unmatched IF-THEN.
1215 (save-match-data 1404 (save-match-data
1216 (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") 1405 (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
1217 ;; Multi-line if-then. 1406 ;; Multi-line if-then.
1218 (let (then-test) 1407 (let (then-test)
1219 (while 1408 (while
1220 (and (= (forward-line 1) 0) 1409 (and (zerop (forward-line 1))
1221 ;; Search forward for then. 1410 ;; Search forward for then.
1222 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]") 1411 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")
1223 (not 1412 (not
1224 (setq then-test 1413 (setq then-test
1225 (looking-at 1414 (looking-at
1228 ;; Sitting on one. 1417 ;; Sitting on one.
1229 (match-beginning 0) 1418 (match-beginning 0)
1230 ;; Search for one. 1419 ;; Search for one.
1231 (save-excursion 1420 (save-excursion
1232 (let ((count 1)) 1421 (let ((count 1))
1233 (while (and (not (= count 0)) 1422 (while (and (not (zerop count))
1234 (not (eq (fortran-previous-statement) 'first-statement)) 1423 (not (eq (fortran-previous-statement) 'first-statement))
1235 ;; Keep local to subprogram. 1424 ;; Keep local to subprogram.
1236 (not (and (looking-at fortran-end-prog-re) 1425 (not (and (looking-at fortran-end-prog-re)
1237 (fortran-check-end-prog-re)))) 1426 (fortran-check-end-prog-re))))
1238 (skip-chars-forward " \t0-9") 1427 (skip-chars-forward " \t0-9")
1239 (cond ((looking-at fortran-if-start-re) 1428 (cond ((looking-at fortran-if-start-re)
1240 (save-excursion 1429 (save-excursion
1241 (if (or 1430 (if (or
1242 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") 1431 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
1243 (let (then-test) ; Multi-line if-then. 1432 (let (then-test) ; multi-line if-then
1244 (while 1433 (while
1245 (and 1434 (and
1246 (= (forward-line 1) 0) 1435 (zerop (forward-line 1))
1247 ;; Search forward for then. 1436 ;; Search forward for then.
1248 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]") 1437 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")
1249 (not 1438 (not
1250 (setq then-test 1439 (setq then-test
1251 (looking-at 1440 (looking-at
1252 (concat ".*then\\b[ \t]*" 1441 (concat ".*then\\b[ \t]*"
1253 "[^ \t(=a-z0-9]")))))) 1442 "[^ \t(=a-z0-9]"))))))
1254 then-test)) 1443 then-test))
1255 (setq count (- count 1))))) 1444 (setq count (1- count)))))
1256 ((looking-at "end[ \t]*if\\b") 1445 ((looking-at "end[ \t]*if\\b")
1257 (setq count (+ count 1))))) 1446 (setq count (1+ count)))))
1258 (and (= count 0) 1447 (and (zerop count)
1259 ;; All pairs accounted for. 1448 ;; All pairs accounted for.
1260 (point))))))) 1449 (point)))))))
1450
1261 1451
1262 (defun fortran-indent-line () 1452 (defun fortran-indent-line ()
1263 "Indent current Fortran line based on its contents and on previous lines." 1453 "Indent current Fortran line based on its contents and on previous lines."
1264 (interactive) 1454 (interactive "*")
1265 (let ((cfi (fortran-calculate-indent))) 1455 (let ((cfi (fortran-calculate-indent)))
1266 (save-excursion 1456 (save-excursion
1267 (beginning-of-line) 1457 (beginning-of-line)
1268 (if (or (not (= cfi (fortran-current-line-indentation))) 1458 (if (or (not (= cfi (fortran-current-line-indentation)))
1269 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t) 1459 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t)
1273 (if (fortran-find-comment-start-skip) 1463 (if (fortran-find-comment-start-skip)
1274 (fortran-indent-comment)))) 1464 (fortran-indent-comment))))
1275 ;; Never leave point in left margin. 1465 ;; Never leave point in left margin.
1276 (if (< (current-column) cfi) 1466 (if (< (current-column) cfi)
1277 (move-to-column cfi)) 1467 (move-to-column cfi))
1278 (if (and auto-fill-function 1468 (and auto-fill-function
1279 (> (save-excursion (end-of-line) (current-column)) 1469 (> (save-excursion (end-of-line) (current-column))
1280 fill-column)) 1470 fill-column)
1281 (save-excursion 1471 (save-excursion
1282 (end-of-line) 1472 (end-of-line)
1283 (fortran-fill))) 1473 (fortran-fill)))
1284 (if fortran-blink-matching-if 1474 (when fortran-blink-matching-if
1285 (progn 1475 (fortran-blink-matching-if)
1286 (fortran-blink-matching-if) 1476 (fortran-blink-matching-do))))
1287 (fortran-blink-matching-do)))))
1288 1477
1289 (defun fortran-auto-fill () 1478 (defun fortran-auto-fill ()
1479 "Function to use for `normal-auto-fill-function' in Fortran mode."
1290 (if (> (current-column) (current-fill-column)) 1480 (if (> (current-column) (current-fill-column))
1291 (let ((cfi (fortran-calculate-indent))) 1481 (let ((cfi (fortran-calculate-indent)))
1292 (save-excursion 1482 (save-excursion
1293 (beginning-of-line) 1483 (beginning-of-line)
1294 (if (or (not (= cfi (fortran-current-line-indentation))) 1484 (if (or (not (= cfi (fortran-current-line-indentation)))
1307 ;; Historically this was a separate function which advertised itself 1497 ;; Historically this was a separate function which advertised itself
1308 ;; as reindenting but only did so where `most likely to be necessary'. 1498 ;; as reindenting but only did so where `most likely to be necessary'.
1309 (defalias 'fortran-indent-new-line 'reindent-then-newline-and-indent) 1499 (defalias 'fortran-indent-new-line 'reindent-then-newline-and-indent)
1310 1500
1311 (defun fortran-indent-subprogram () 1501 (defun fortran-indent-subprogram ()
1312 "Properly indent the Fortran subprogram which contains point." 1502 "Properly indent the Fortran subprogram containing point."
1313 (interactive) 1503 (interactive "*")
1314 (save-excursion 1504 (save-excursion
1315 (mark-defun) 1505 (mark-defun)
1316 (message "Indenting subprogram...") 1506 (message "Indenting subprogram...")
1317 (indent-region (point) (mark) nil)) 1507 (indent-region (point) (mark) nil))
1318 (message "Indenting subprogram...done.")) 1508 (message "Indenting subprogram...done."))
1326 fortran-minimum-statement-indent-fixed))) 1516 fortran-minimum-statement-indent-fixed)))
1327 (save-excursion 1517 (save-excursion
1328 (setq first-statement (fortran-previous-statement)) 1518 (setq first-statement (fortran-previous-statement))
1329 (if first-statement 1519 (if first-statement
1330 (setq icol fortran-minimum-statement-indent) 1520 (setq icol fortran-minimum-statement-indent)
1331 (progn 1521 (if (= (point) (point-min))
1332 (if (= (point) (point-min)) 1522 (setq icol fortran-minimum-statement-indent)
1333 (setq icol fortran-minimum-statement-indent) 1523 (setq icol (fortran-current-line-indentation)))
1334 (setq icol (fortran-current-line-indentation))) 1524 (skip-chars-forward " \t0-9")
1335 (skip-chars-forward " \t0-9") 1525 (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(")
1336 (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(") 1526 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]")
1337 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]") 1527 (let (then-test) ; multi-line if-then
1338 (let (then-test) ;multi-line if-then 1528 (while (and (zerop (forward-line 1))
1339 (while (and (= (forward-line 1) 0) 1529 ;; Search forward for then.
1340 ;;search forward for then 1530 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")
1341 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]") 1531 (not (setq then-test
1342 (not (setq then-test 1532 (looking-at
1343 (looking-at 1533 ".*then\\b[ \t]\
1344 ".*then\\b[ \t]\
1345 *[^ \t_$(=a-z0-9]"))))) 1534 *[^ \t_$(=a-z0-9]")))))
1346 then-test)) 1535 then-test))
1347 (setq icol (+ icol fortran-if-indent)))) 1536 (setq icol (+ icol fortran-if-indent))))
1348 ((looking-at "else\\(if\\)?\\b") 1537 ((looking-at "else\\(if\\)?\\b")
1349 (setq icol (+ icol fortran-if-indent))) 1538 (setq icol (+ icol fortran-if-indent)))
1350 ((looking-at "select[ \t]*case[ \t](.*)") 1539 ((looking-at "select[ \t]*case[ \t](.*)")
1351 (setq icol (+ icol fortran-if-indent))) 1540 (setq icol (+ icol fortran-if-indent)))
1352 ((looking-at "case[ \t]*(.*)") 1541 ((looking-at "case[ \t]*(.*)")
1353 (setq icol (+ icol fortran-if-indent))) 1542 (setq icol (+ icol fortran-if-indent)))
1354 ((looking-at "case[ \t]*default\\b") 1543 ((looking-at "case[ \t]*default\\b")
1355 (setq icol (+ icol fortran-if-indent))) 1544 (setq icol (+ icol fortran-if-indent)))
1356 ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b") 1545 ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
1357 (setq icol (+ icol fortran-if-indent))) 1546 (setq icol (+ icol fortran-if-indent)))
1358 ((looking-at "where[ \t]*(.*)[ \t]*\n") 1547 ((looking-at "where[ \t]*(.*)[ \t]*\n")
1359 (setq icol (+ icol fortran-if-indent))) 1548 (setq icol (+ icol fortran-if-indent)))
1360 ((looking-at "do\\b") 1549 ((looking-at "do\\b")
1361 (setq icol (+ icol fortran-do-indent))) 1550 (setq icol (+ icol fortran-do-indent)))
1362 ((looking-at 1551 ((looking-at
1363 "\\(structure\\|union\\|map\\|interface\\)\ 1552 "\\(structure\\|union\\|map\\|interface\\)\
1364 \\b[ \t]*[^ \t=(a-z]") 1553 \\b[ \t]*[^ \t=(a-z]")
1365 (setq icol (+ icol fortran-structure-indent))) 1554 (setq icol (+ icol fortran-structure-indent)))
1366 ((and (looking-at fortran-end-prog-re1) 1555 ((and (looking-at fortran-end-prog-re1)
1367 (fortran-check-end-prog-re)) 1556 (fortran-check-end-prog-re))
1368 ;; Previous END resets indent to minimum 1557 ;; Previous END resets indent to minimum.
1369 (setq icol fortran-minimum-statement-indent)))))) 1558 (setq icol fortran-minimum-statement-indent)))))
1370 (save-excursion 1559 (save-excursion
1371 (beginning-of-line) 1560 (beginning-of-line)
1372 (cond ((looking-at "[ \t]*$")) 1561 (cond ((looking-at "[ \t]*$"))
1373 ;; Check for directive before comment, so as not to indent. 1562 ;; Check for directive before comment, so as not to indent.
1374 ((looking-at fortran-directive-re) 1563 ((looking-at fortran-directive-re)
1378 (setq icol (+ icol fortran-comment-line-extra-indent))) 1567 (setq icol (+ icol fortran-comment-line-extra-indent)))
1379 ((eq fortran-comment-indent-style 'fixed) 1568 ((eq fortran-comment-indent-style 'fixed)
1380 (setq icol (+ fortran-minimum-statement-indent 1569 (setq icol (+ fortran-minimum-statement-indent
1381 fortran-comment-line-extra-indent)))) 1570 fortran-comment-line-extra-indent))))
1382 (setq fortran-minimum-statement-indent 0)) 1571 (setq fortran-minimum-statement-indent 0))
1383 ((or (looking-at (concat "[ \t]*" 1572 ((or (looking-at (concat "[ \t]*"
1384 (regexp-quote 1573 (regexp-quote
1385 fortran-continuation-string))) 1574 fortran-continuation-string)))
1386 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")) 1575 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]"))
1387 (setq icol (+ icol fortran-continuation-indent))) 1576 (skip-chars-forward " \t")
1577 ;; Do not introduce extra whitespace into a broken string.
1578 (setq icol
1579 (if (fortran-is-in-string-p (point))
1580 6
1581 (+ icol fortran-continuation-indent))))
1388 (first-statement) 1582 (first-statement)
1389 ((and fortran-check-all-num-for-matching-do 1583 ((and fortran-check-all-num-for-matching-do
1390 (looking-at "[ \t]*[0-9]+") 1584 (looking-at "[ \t]*[0-9]+")
1391 (fortran-check-for-matching-do)) 1585 (fortran-check-for-matching-do))
1392 (setq icol (- icol fortran-do-indent))) 1586 (setq icol (- icol fortran-do-indent)))
1412 (fortran-check-end-prog-re) 1606 (fortran-check-end-prog-re)
1413 (not (= icol fortran-minimum-statement-indent))) 1607 (not (= icol fortran-minimum-statement-indent)))
1414 (message "Warning: `end' not in column %d. Probably\ 1608 (message "Warning: `end' not in column %d. Probably\
1415 an unclosed block." fortran-minimum-statement-indent)))))) 1609 an unclosed block." fortran-minimum-statement-indent))))))
1416 (max fortran-minimum-statement-indent icol))) 1610 (max fortran-minimum-statement-indent icol)))
1611
1417 1612
1418 (defun fortran-current-line-indentation () 1613 (defun fortran-current-line-indentation ()
1419 "Indentation of current line, ignoring Fortran line number or continuation. 1614 "Indentation of current line, ignoring Fortran line number or continuation.
1420 This is the column position of the first non-whitespace character 1615 This is the column position of the first non-whitespace character
1421 aside from the line number and/or column 5/8 line-continuation character. 1616 aside from the line number and/or column 5/8 line-continuation character.
1437 ;; Move past whitespace. 1632 ;; Move past whitespace.
1438 (skip-chars-forward " \t") 1633 (skip-chars-forward " \t")
1439 (current-column))) 1634 (current-column)))
1440 1635
1441 (defun fortran-indent-to-column (col) 1636 (defun fortran-indent-to-column (col)
1442 "Indent current line with spaces to column COL. 1637 "Indent current line to column COL.
1443 notes: 1) A non-zero/non-blank character in column 5 indicates a continuation 1638 notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
1444 line, and this continuation character is retained on indentation; 1639 line, and this continuation character is retained on indentation;
1445 2) If `fortran-continuation-string' is the first non-whitespace 1640 2) If `fortran-continuation-string' is the first non-whitespace
1446 character, this is a continuation line; 1641 character, this is a continuation line;
1447 3) A non-continuation line which has a number as the first 1642 3) A non-continuation line which has a number as the first
1452 (if (looking-at fortran-comment-line-start-skip) 1647 (if (looking-at fortran-comment-line-start-skip)
1453 (if fortran-comment-indent-style 1648 (if fortran-comment-indent-style
1454 (let* ((char (if (stringp fortran-comment-indent-char) 1649 (let* ((char (if (stringp fortran-comment-indent-char)
1455 (aref fortran-comment-indent-char 0) 1650 (aref fortran-comment-indent-char 0)
1456 fortran-comment-indent-char)) 1651 fortran-comment-indent-char))
1457 (chars (string ? ?\t char))) 1652 (chars (string ?\s ?\t char)))
1458 (goto-char (match-end 0)) 1653 (goto-char (match-end 0))
1459 (skip-chars-backward chars) 1654 (skip-chars-backward chars)
1460 (delete-region (point) (progn (skip-chars-forward chars) 1655 (delete-region (point) (progn (skip-chars-forward chars)
1461 (point))) 1656 (point)))
1462 (insert-char char (- col (current-column))))) 1657 (insert-char char (- col (current-column)))))
1463 (if (looking-at "\t[1-9]") 1658 (if (looking-at "\t[1-9]")
1464 (if indent-tabs-mode 1659 (if indent-tabs-mode
1465 (goto-char (match-end 0)) 1660 (goto-char (match-end 0))
1466 (delete-char 2) 1661 (delete-char 2)
1467 (insert-char ? 5) 1662 (insert-char ?\s 5)
1468 (insert fortran-continuation-string)) 1663 (insert fortran-continuation-string))
1469 (if (looking-at " \\{5\\}[^ 0\n]") 1664 (if (looking-at " \\{5\\}[^ 0\n]")
1470 (if indent-tabs-mode 1665 (if indent-tabs-mode
1471 (progn (delete-char 6) 1666 (progn (delete-char 6)
1472 (insert ?\t (fortran-numerical-continuation-char) 1)) 1667 (insert ?\t (fortran-numerical-continuation-char) 1))
1473 (forward-char 6)) 1668 (forward-char 6))
1474 (delete-horizontal-space) 1669 (delete-horizontal-space)
1475 ;; Put line number in columns 0-4 1670 ;; Put line number in columns 0-4, or
1476 ;; or put continuation character in column 5. 1671 ;; continuation character in column 5.
1477 (cond ((eobp)) 1672 (cond ((eobp))
1478 ((looking-at (regexp-quote fortran-continuation-string)) 1673 ((looking-at (regexp-quote fortran-continuation-string))
1479 (if indent-tabs-mode 1674 (if indent-tabs-mode
1480 (progn 1675 (progn
1481 (indent-to 1676 (indent-to
1495 ;; Point is now after any continuation character or line number. 1690 ;; Point is now after any continuation character or line number.
1496 ;; Put body of statement where specified. 1691 ;; Put body of statement where specified.
1497 (delete-horizontal-space) 1692 (delete-horizontal-space)
1498 (indent-to col) 1693 (indent-to col)
1499 ;; Indent any comment following code on the same line. 1694 ;; Indent any comment following code on the same line.
1500 (if (fortran-find-comment-start-skip) 1695 (when (fortran-find-comment-start-skip)
1501 (progn (goto-char (match-beginning 0)) 1696 (goto-char (match-beginning 0))
1502 (if (not (= (current-column) (fortran-comment-indent))) 1697 (unless (= (current-column) (fortran-comment-indent))
1503 (progn (delete-horizontal-space) 1698 (delete-horizontal-space)
1504 (indent-to (fortran-comment-indent))))))))) 1699 (indent-to (fortran-comment-indent)))))))
1505 1700
1506 (defun fortran-line-number-indented-correctly-p () 1701 (defun fortran-line-number-indented-correctly-p ()
1507 "Return t if current line's line number is correctly indented. 1702 "Return t if current line's line number is correctly indented.
1508 Do not call if there is no line number." 1703 Do not call if there is no line number."
1509 (save-excursion 1704 (save-excursion
1519 Otherwise return nil." 1714 Otherwise return nil."
1520 (let ((case-fold-search t) 1715 (let ((case-fold-search t)
1521 charnum) 1716 charnum)
1522 (save-excursion 1717 (save-excursion
1523 (beginning-of-line) 1718 (beginning-of-line)
1524 (if (looking-at "[ \t]*[0-9]+") 1719 (when (looking-at "[ \t]*[0-9]+")
1525 (progn 1720 (skip-chars-forward " \t")
1526 (skip-chars-forward " \t") 1721 (skip-chars-forward "0") ; skip past leading zeros
1527 (skip-chars-forward "0") ;skip past leading zeros 1722 (setq charnum
1528 (setq charnum 1723 (buffer-substring (point) (progn
1529 (buffer-substring (point) (progn 1724 (skip-chars-forward "0-9")
1530 (skip-chars-forward "0-9") 1725 (point))))
1531 (point)))) 1726 (beginning-of-line)
1532 (beginning-of-line) 1727 (save-restriction
1533 (save-restriction 1728 (save-excursion
1534 (save-excursion 1729 (narrow-to-defun)
1535 (narrow-to-defun) 1730 (and (re-search-backward
1536 (and (re-search-backward 1731 (concat
1537 (concat 1732 "\\(^[ \t0-9]*do[ \t]*0*"
1538 "\\(^[ \t0-9]*do[ \t]*0*" 1733 charnum "\\b\\)\\|" "\\(^[ \t]*0*"
1539 charnum "\\b\\)\\|" "\\(^[ \t]*0*" 1734 charnum "\\b\\)")
1540 charnum "\\b\\)") 1735 nil t)
1541 nil t) 1736 (looking-at
1542 (looking-at 1737 (concat "^[ \t0-9]*do[ \t]*0*"
1543 (concat "^[ \t0-9]*do[ \t]*0*" 1738 charnum)))))))))
1544 charnum))))))))))
1545 1739
1546 (defun fortran-find-comment-start-skip (&optional all) 1740 (defun fortran-find-comment-start-skip (&optional all)
1547 "Move to past `comment-start-skip' found on current line. 1741 "Move to past `comment-start-skip' found on current line.
1548 Return non-nil if `comment-start-skip' found, nil if not. 1742 Return non-nil if `comment-start-skip' found, nil if not.
1549 If ALL is nil, only match comments that start in column > 0." 1743 If ALL is nil, only match comments that start in column > 0."
1550 (interactive)
1551 ;; Hopefully at some point we can just use the line below! -stef 1744 ;; Hopefully at some point we can just use the line below! -stef
1552 ;; (comment-search-forward (line-end-position) t)) 1745 ;; (comment-search-forward (line-end-position) t))
1553 (when (or all comment-start-skip) 1746 (when (or all comment-start-skip)
1554 (let ((pos (point)) 1747 (let ((pos (point))
1555 (css (if comment-start-skip 1748 (css (if comment-start-skip
1564 (fortran-find-comment-start-skip all))) 1757 (fortran-find-comment-start-skip all)))
1565 (point) 1758 (point)
1566 (goto-char pos) 1759 (goto-char pos)
1567 nil))))) 1760 nil)))))
1568 1761
1569 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel) 1762 ;; From: ralf@up3aud1.gwdg.de (Ralf Fassel)
1570 ;; Test if TAB format continuation lines work. 1763 ;; Test if TAB format continuation lines work.
1571 (defun fortran-is-in-string-p (where) 1764 (defun fortran-is-in-string-p (where)
1572 "Return non-nil iff WHERE (a buffer position) is inside a Fortran string." 1765 "Return non-nil iff WHERE (a buffer position) is inside a Fortran string."
1573 (save-excursion 1766 (save-excursion
1574 (goto-char where) 1767 (goto-char where)
1575 (cond 1768 (cond
1576 ((bolp) nil) ; bol is never inside a string 1769 ((bolp) nil) ; bol is never inside a string
1577 ((save-excursion ; comment lines too 1770 ((save-excursion ; comment lines too
1578 (beginning-of-line) 1771 (beginning-of-line)
1579 (looking-at fortran-comment-line-start-skip)) nil) 1772 (looking-at fortran-comment-line-start-skip)) nil)
1580 (t (let (;; ok, serious now. Init some local vars: 1773 (t (let ((parse-state '(0 nil nil nil nil nil 0))
1581 (parse-state '(0 nil nil nil nil nil 0))
1582 (quoted-comment-start (if comment-start 1774 (quoted-comment-start (if comment-start
1583 (regexp-quote comment-start))) 1775 (regexp-quote comment-start)))
1584 (not-done t) 1776 (not-done t)
1585 parse-limit end-of-line) 1777 parse-limit end-of-line)
1586 ;; move to start of current statement 1778 ;; Move to start of current statement.
1587 (fortran-next-statement) 1779 (fortran-next-statement)
1588 (fortran-previous-statement) 1780 (fortran-previous-statement)
1589 ;; now parse up to WHERE 1781 ;; Now parse up to WHERE.
1590 (while not-done 1782 (while not-done
1591 (if (or ;; skip to next line if: 1783 (if (or ;; Skip to next line if:
1592 ;; - comment line? 1784 ;; - comment line?
1593 (looking-at fortran-comment-line-start-skip) 1785 (looking-at fortran-comment-line-start-skip)
1594 ;; - at end of line? 1786 ;; - at end of line?
1595 (eolp) 1787 (eolp)
1596 ;; - not in a string and after comment-start? 1788 ;; - not in a string and after comment-start?
1599 (equal comment-start 1791 (equal comment-start
1600 (char-to-string (preceding-char))))) 1792 (char-to-string (preceding-char)))))
1601 (if (> (forward-line) 0) 1793 (if (> (forward-line) 0)
1602 (setq not-done nil)) 1794 (setq not-done nil))
1603 ;; else: 1795 ;; else:
1604 ;; if we are at beginning of code line, skip any 1796 ;; If we are at beginning of code line, skip any
1605 ;; whitespace, labels and tab continuation markers. 1797 ;; whitespace, labels and tab continuation markers.
1606 (if (bolp) (skip-chars-forward " \t0-9")) 1798 (if (bolp) (skip-chars-forward " \t0-9"))
1607 ;; if we are in column <= 5 now, check for continuation char 1799 ;; If we are in column <= 5 now, check for continuation char.
1608 (cond ((= 5 (current-column)) (forward-char 1)) 1800 (cond ((= 5 (current-column)) (forward-char 1))
1609 ((and (< (current-column) 5) 1801 ((and (< (current-column) 5)
1610 (equal fortran-continuation-string 1802 (equal fortran-continuation-string
1611 (char-to-string (following-char))) 1803 (char-to-string (following-char)))
1612 (forward-char 1)))) 1804 (forward-char 1))))
1613 ;; find out parse-limit from here 1805 ;; Find out parse-limit from here.
1614 (setq end-of-line (line-end-position)) 1806 (setq end-of-line (line-end-position))
1615 (setq parse-limit (min where end-of-line)) 1807 (setq parse-limit (min where end-of-line))
1616 ;; parse max up to comment-start, if non-nil and in current line 1808 ;; Parse max up to comment-start, if non-nil and in current line.
1617 (if comment-start 1809 (if comment-start
1618 (save-excursion 1810 (save-excursion
1619 (if (re-search-forward quoted-comment-start end-of-line t) 1811 (if (re-search-forward quoted-comment-start end-of-line t)
1620 (setq parse-limit (min (point) parse-limit))))) 1812 (setq parse-limit (min (point) parse-limit)))))
1621 ;; now parse if still in limits 1813 ;; Now parse if still in limits.
1622 (if (< (point) where) 1814 (if (< (point) where)
1623 (setq parse-state (parse-partial-sexp 1815 (setq parse-state (parse-partial-sexp
1624 (point) parse-limit nil nil parse-state)) 1816 (point) parse-limit nil nil parse-state))
1625 (setq not-done nil)))) 1817 (setq not-done nil))))
1626 ;; result is 1818 ;; Result.
1627 (nth 3 parse-state)))))) 1819 (nth 3 parse-state))))))
1628 1820
1629 ;; From old version. 1821 ;; From old version.
1630 (defalias 'fortran-auto-fill-mode 'auto-fill-mode) 1822 (defalias 'fortran-auto-fill-mode 'auto-fill-mode)
1631 1823
1632 (defun fortran-fill () 1824 (defun fortran-fill ()
1825 "Fill the current line at an appropriate point(s)."
1633 (let* ((auto-fill-function #'fortran-auto-fill) 1826 (let* ((auto-fill-function #'fortran-auto-fill)
1634 (opoint (point)) 1827 (opoint (point))
1635 (bol (line-beginning-position)) 1828 (bol (line-beginning-position))
1636 (eol (line-end-position)) 1829 (eol (line-end-position))
1637 (bos (min eol (+ bol (fortran-current-line-indentation)))) 1830 (bos (min eol (+ bol (fortran-current-line-indentation))))
1831 ;; If in a string at fill-column, break it either before the
1832 ;; initial quote, or at fill-col (if string is too long).
1638 (quote 1833 (quote
1639 (save-excursion 1834 (save-excursion
1640 (goto-char bol) 1835 (goto-char bol)
1641 (if (looking-at fortran-comment-line-start-skip) 1836 ;; OK to break quotes on comment lines.
1642 nil ; OK to break quotes on comment lines. 1837 (unless (looking-at fortran-comment-line-start-skip)
1643 (move-to-column fill-column) 1838 (let (fcpoint start)
1644 (if (fortran-is-in-string-p (point)) 1839 (move-to-column fill-column)
1645 (save-excursion (re-search-backward "\\S\"\\s\"\\S\"" bol t) 1840 (when (fortran-is-in-string-p (setq fcpoint (point)))
1646 (if fortran-break-before-delimiters 1841 (save-excursion
1647 (point) 1842 (re-search-backward "\\S\"\\s\"\\S\"?" bol t)
1648 (1+ (point)))))))) 1843 (setq start
1649 ;; decide where to split the line. If a position for a quoted 1844 (if fortran-break-before-delimiters
1845 (point)
1846 (1+ (point)))))
1847 (if (re-search-forward "\\S\"\\s\"\\S\"" eol t)
1848 (backward-char 2))
1849 ;; If the current string is longer than (fill-column
1850 ;; - 6) chars, break it at the fill column (else
1851 ;; infinite loop).
1852 (if (> (- (point) start)
1853 (- fill-column 6 fortran-continuation-indent))
1854 fcpoint
1855 start))))))
1856 ;; Decide where to split the line. If a position for a quoted
1650 ;; string was found above then use that, else break the line 1857 ;; string was found above then use that, else break the line
1651 ;; before the last delimiter. 1858 ;; before/after the last delimiter.
1652 ;; Delimiters are whitespace, commas, and operators.
1653 ;; Will break before a pair of *'s.
1654 (fill-point 1859 (fill-point
1655 (or quote 1860 (or quote
1656 (save-excursion 1861 (save-excursion
1657 (move-to-column (1+ fill-column)) 1862 ;; If f-b-b-d is t, have an extra column to play with,
1658 (skip-chars-backward "^ \t\n,'+-/*=)" 1863 ;; since delimiter gets shifted to new line.
1659 ;;; (if fortran-break-before-delimiters 1864 (move-to-column (if fortran-break-before-delimiters
1660 ;;; "^ \t\n,'+-/*=" "^ \t\n,'+-/*=)") 1865 (1+ fill-column)
1661 ) 1866 fill-column))
1662 (if (<= (point) (1+ bos)) 1867 (let ((repeat t))
1663 (progn 1868 (while repeat
1664 (move-to-column (1+ fill-column)) 1869 (setq repeat nil)
1665 ;;what is this doing??? 1870 ;; Adapted from f90-find-breakpoint.
1666 (if (not (re-search-forward "[\t\n,'+-/*)=]" eol t)) 1871 (re-search-backward fortran-break-delimiters-re bol)
1667 (goto-char bol)))) 1872 (if (not fortran-break-before-delimiters)
1873 (if (looking-at fortran-no-break-re)
1874 ;; Deal with cases such as "**" split over
1875 ;; fill-col. Simpler alternative would be
1876 ;; to start from (1- fill-column) above.
1877 (if (> (+ 2 (current-column)) fill-column)
1878 (setq repeat t)
1879 (forward-char 2))
1880 (forward-char 1))
1881 (backward-char)
1882 (or (looking-at fortran-no-break-re)
1883 (forward-char)))))
1884 ;; Line indented beyond fill-column?
1885 (when (<= (point) bos)
1886 (move-to-column (1+ fill-column))
1887 ;; What is this doing???
1888 (or (re-search-forward "[\t\n,'+-/*)=]" eol t)
1889 (goto-char bol)))
1668 (if (bolp) 1890 (if (bolp)
1669 (re-search-forward "[ \t]" opoint t) 1891 (re-search-forward "[ \t]" opoint t))
1670 (backward-char) 1892 (point)))))
1671 (if (looking-at "\\s\"") 1893 ;; If we are in an in-line comment, don't break unless the
1672 (forward-char)
1673 (skip-chars-backward " \t\*")))
1674 (if fortran-break-before-delimiters
1675 (point)
1676 (1+ (point)))))))
1677 ;; if we are in an in-line comment, don't break unless the
1678 ;; line of code is longer than it should be. Otherwise 1894 ;; line of code is longer than it should be. Otherwise
1679 ;; break the line at the column computed above. 1895 ;; break the line at the column computed above.
1680 ;; 1896 ;;
1681 ;; Need to use fortran-find-comment-start-skip to make sure that quoted !'s 1897 ;; Need to use fortran-find-comment-start-skip to make sure that
1682 ;; don't prevent a break. 1898 ;; quoted !'s don't prevent a break.
1683 (when (and (save-excursion 1899 (when (and (save-excursion
1684 (beginning-of-line) 1900 (beginning-of-line)
1685 (if (not (fortran-find-comment-start-skip)) 1901 (if (not (fortran-find-comment-start-skip))
1686 t 1902 t
1687 (goto-char (match-beginning 0)) 1903 (goto-char (match-beginning 0))
1698 (goto-char fill-point) 1914 (goto-char fill-point)
1699 (fortran-break-line) 1915 (fortran-break-line)
1700 (end-of-line)))) 1916 (end-of-line))))
1701 1917
1702 (defun fortran-break-line () 1918 (defun fortran-break-line ()
1919 "Call `fortran-split-line'. Joins continuation lines first, then refills."
1703 (let ((opoint (point)) 1920 (let ((opoint (point))
1704 (bol (line-beginning-position)) 1921 (bol (line-beginning-position))
1705 (comment-string 1922 (comment-string
1706 (save-excursion 1923 (save-excursion
1707 (if (fortran-find-comment-start-skip) 1924 (if (fortran-find-comment-start-skip)
1708 (delete-and-extract-region 1925 (delete-and-extract-region
1709 (match-beginning 0) (line-end-position)))))) 1926 (match-beginning 0) (line-end-position))))))
1710 ;; Forward line 1 really needs to go to next non white line 1927 ;; Forward line 1 really needs to go to next non white line.
1711 (if (save-excursion (forward-line) 1928 (if (save-excursion (forward-line)
1712 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]")) 1929 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]"))
1713 (progn 1930 (progn
1714 (end-of-line) 1931 (end-of-line)
1715 (delete-region (point) (match-end 0)) 1932 (delete-region (point) (match-end 0))
1724 (indent-to (fortran-comment-indent)) 1941 (indent-to (fortran-comment-indent))
1725 (insert comment-string))))) 1942 (insert comment-string)))))
1726 1943
1727 (defun fortran-analyze-file-format () 1944 (defun fortran-analyze-file-format ()
1728 "Return nil if fixed format is used, t if TAB formatting is used. 1945 "Return nil if fixed format is used, t if TAB formatting is used.
1729 Use `fortran-tab-mode-default' if no non-comment statements are found in the 1946 Use `fortran-tab-mode-default' if no non-comment statements are found
1730 file before the end or the first `fortran-analyze-depth' lines." 1947 before the end or in the first `fortran-analyze-depth' lines."
1731 (let ((i 0)) 1948 (let ((i 0))
1732 (save-excursion 1949 (save-excursion
1733 (goto-char (point-min)) 1950 (goto-char (point-min))
1734 (setq i 0)
1735 (while (not (or 1951 (while (not (or
1736 (eobp) 1952 (eobp)
1737 (eq (char-after) ?\t) 1953 (eq (char-after) ?\t)
1738 (looking-at " \\{6\\}") 1954 (looking-at " \\{6\\}")
1739 (> i fortran-analyze-depth))) 1955 (> i fortran-analyze-depth)))
1740 (forward-line) 1956 (forward-line)
1741 (setq i (1+ i))) 1957 (setq i (1+ i)))
1742 (cond 1958 (cond
1743 ((eq (char-after) ?\t) t) 1959 ((eq (char-after) ?\t) t)
1744 ((looking-at " \\{6\\}") nil) 1960 ((looking-at " \\{6\\}") nil)
1745 (fortran-tab-mode-default t) 1961 (t fortran-tab-mode-default)))))
1746 (t nil)))))
1747
1748 (or (assq 'fortran-tab-mode-string minor-mode-alist)
1749 (setq minor-mode-alist (cons
1750 '(fortran-tab-mode-string
1751 (indent-tabs-mode fortran-tab-mode-string))
1752 minor-mode-alist)))
1753 1962
1754 (defun fortran-fill-paragraph (&optional justify) 1963 (defun fortran-fill-paragraph (&optional justify)
1755 "Fill surrounding comment block as paragraphs, else fill statement. 1964 "Fill surrounding comment block as paragraphs, else fill statement.
1756 Intended as the value of `fill-paragraph-function'." 1965 Intended as the value of `fill-paragraph-function'.
1757 (interactive "P") 1966 A comment block is filled by calling `fill-comment-paragraph' with
1967 argument JUSTIFY, otherwise `fortran-fill-statement' is called.
1968 Always returns non-nil (to prevent `fill-paragraph' being called)."
1969 (interactive "*P")
1758 (or (fill-comment-paragraph justify) 1970 (or (fill-comment-paragraph justify)
1759 (fortran-fill-statement) 1971 (fortran-fill-statement)
1760 t)) 1972 t))
1761 1973
1762 (defun fortran-fill-statement () 1974 (defun fortran-fill-statement ()
1763 "Fill a fortran statement up to `fill-column'." 1975 "Fill a Fortran statement up to `fill-column'."
1764 (interactive) 1976 (interactive "*")
1765 (let ((auto-fill-function #'fortran-auto-fill)) 1977 (let ((auto-fill-function #'fortran-auto-fill))
1766 (if (not (save-excursion 1978 (unless (save-excursion
1767 (beginning-of-line) 1979 (beginning-of-line)
1768 (or (looking-at "[ \t]*$") 1980 (or (looking-at "[ \t]*$")
1769 (looking-at fortran-comment-line-start-skip) 1981 (looking-at fortran-comment-line-start-skip)
1770 (and comment-start-skip 1982 (and comment-start-skip
1771 (looking-at (concat "[ \t]*" comment-start-skip)))))) 1983 (looking-at (concat "[ \t]*" comment-start-skip)))))
1772 (save-excursion 1984 (save-excursion
1773 ;; Find beginning of statement. 1985 ;; Find beginning of statement.
1774 (fortran-next-statement) 1986 (fortran-next-statement)
1775 (fortran-previous-statement) 1987 (fortran-previous-statement)
1776 ;; Re-indent initially. 1988 ;; Re-indent initially.
1777 (fortran-indent-line) 1989 (fortran-indent-line)
1778 ;; Replace newline plus continuation field plus indentation with 1990 ;; Replace newline plus continuation field plus indentation with
1779 ;; single space. 1991 ;; single space.
1780 (while (progn 1992 (while (progn
1781 (forward-line) 1993 (forward-line)
1782 (fortran-remove-continuation))) 1994 (fortran-remove-continuation)))
1783 (fortran-previous-statement))) 1995 (fortran-previous-statement)))
1784 (fortran-indent-line))) 1996 (fortran-indent-line)))
1785 1997
1786 (defun fortran-strip-sequence-nos (&optional do-space) 1998 (defun fortran-strip-sequence-nos (&optional do-space)
1787 "Delete all text in column 72 and up (assumed to be sequence numbers). 1999 "Delete all text in column 72 and up (assumed to be sequence numbers).
1788 Normally also deletes trailing whitespace after stripping such text. 2000 Normally also deletes trailing whitespace after stripping such text.
1789 Supplying prefix arg DO-SPACE prevents stripping the whitespace." 2001 Supplying prefix arg DO-SPACE prevents stripping the whitespace."
1790 (interactive "p") 2002 (interactive "*p")
1791 (save-excursion 2003 (save-excursion
1792 (goto-char (point-min)) 2004 (goto-char (point-min))
1793 (while (re-search-forward "^.\\{72\\}\\(.*\\)" nil t) 2005 (while (re-search-forward "^.\\{72\\}\\(.*\\)" nil t)
1794 (replace-match "" nil nil nil 1) 2006 (replace-match "" nil nil nil 1)
1795 (unless do-space (delete-horizontal-space))))) 2007 (unless do-space (delete-horizontal-space)))))
1800 "Function to use for `add-log-current-defun-function' in Fortran mode." 2012 "Function to use for `add-log-current-defun-function' in Fortran mode."
1801 (save-excursion 2013 (save-excursion
1802 ;; We must be inside function body for this to work. 2014 ;; We must be inside function body for this to work.
1803 (fortran-beginning-of-subprogram) 2015 (fortran-beginning-of-subprogram)
1804 (let ((case-fold-search t)) ; case-insensitive 2016 (let ((case-fold-search t)) ; case-insensitive
1805 ;; search for fortran subprogram start 2017 ;; Search for fortran subprogram start.
1806 (if (re-search-forward 2018 (if (re-search-forward
1807 (concat "^[ \t]*\\(program\\|subroutine\\|function" 2019 (concat "^[ \t]*\\(program\\|subroutine\\|function"
1808 "\\|[ \ta-z0-9*()]*[ \t]+function\\|" 2020 "\\|[ \ta-z0-9*()]*[ \t]+function\\|"
1809 "\\(block[ \t]*data\\)\\)") 2021 "\\(block[ \t]*data\\)\\)")
1810 (save-excursion (fortran-end-of-subprogram) 2022 (save-excursion (fortran-end-of-subprogram)
1811 (point)) 2023 (point))
1812 t) 2024 t)
1813 (or (match-string-no-properties 2) 2025 (or (match-string-no-properties 2)
1814 (progn 2026 (progn
1815 ;; move to EOL or before first left paren 2027 ;; Move to EOL or before first left paren.
1816 (if (re-search-forward "[(\n]" nil t) 2028 (if (re-search-forward "[(\n]" nil t)
1817 (progn (backward-char) 2029 (progn (backward-char)
1818 (skip-chars-backward " \t")) 2030 (skip-chars-backward " \t"))
1819 (end-of-line)) 2031 (end-of-line))
1820 ;; Use the name preceding that. 2032 ;; Use the name preceding that.
1822 (point))))) 2034 (point)))))
1823 "main")))) 2035 "main"))))
1824 2036
1825 (provide 'fortran) 2037 (provide 'fortran)
1826 2038
2039 ;;; arch-tag: 74935096-21c4-4cab-8ee5-6ef16090dc04
1827 ;;; fortran.el ends here 2040 ;;; fortran.el ends here