aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1992-11-05 20:25:10 +0000
committerRichard M. Stallman1992-11-05 20:25:10 +0000
commitb8cbdf43f9be7b826a7bb67f1b514064693adc4d (patch)
treeda6f5c8e463394172872c200a2be034a7460fbb9
parent7b937caffbde008ef76d9cd0dfb1936dd3443c69 (diff)
downloademacs-b8cbdf43f9be7b826a7bb67f1b514064693adc4d.tar.gz
emacs-b8cbdf43f9be7b826a7bb67f1b514064693adc4d.zip
version 1.28.8
(fortran-indent-to-column): Make turning of lines that begin with `fortran-continuation-string' into properly formated continuation lines work for fortran TAB mode. Cleaned up some doc strings. (fortran-abbrev-help, fortran-prepare-abbrev-list-buffer): Use `insert-abbrev-table-description' and make buffer in abbrevs-mode. Many changes since version 1.28.3. Added auto-fill-mode, support for some Fortran 90 statements. Adjust comments to conform to new gnu conventions. (fortran-mode): Fix `comment-line-start-skip' by changing \\1 to \\2 and include cpp statements in matching. Changes for auto fill. (fortran-auto-fill-mode, fortran-do-auto-fill, fortran-break-line): New functions to implement auto fill. (fortran-indent-line, fortran-reindent-then-newline-and-indent): Added auto fill support. (find-comment-start-skip, is-in-fortran-string-p): New functions. (fortran-electric-line-number): Works better in overwrite mode. (fortran-indent-comment, fortran-indent-line, fortran-indent-to-column): Use find-comment-start-skip instead of searching for `comment-start-skip'. (fortran-mode, calculate-fortran-indent): Added indentation for fortran 90 statements. (fortran-next-statement, fortran-previous-statement): Bug fixes. (fortran-mode, calculate-fortran-indent, fortran-setup-tab-format-style, fortran-setup-fixed-format-style): `fortran-comment-line-column' meaning changed. Now defaults to 0.
-rw-r--r--lisp/progmodes/fortran.el527
1 files changed, 403 insertions, 124 deletions
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index 044945e6cd9..7ce4d7b810a 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Michael D. Prange <prange@erl.mit.edu> 5;; Author: Michael D. Prange <prange@erl.mit.edu>
6;; Maintainer: bug-fortran-mode@erl.mit.edu 6;; Maintainer: bug-fortran-mode@erl.mit.edu
7;; Version 1.28.3a 7;; Version 1.28.8
8;; Keywords: languages 8;; Keywords: languages
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -25,15 +25,18 @@
25 25
26;;; Commentary: 26;;; Commentary:
27 27
28;;; Written by Michael D. Prange (prange@erl.mit.edu) 28;; fortran.el version 1.28.8, November 5,1992
29;;; Maintained (as of version 1.28) by Stephen A. Wood (saw@hallc1.cebaf.gov) 29;; Many contributions and valuable suggestions by
30;; Lawrence R. Dodd, Ralf Fassel, Ralph Finch, Stephen Gildea,
31;; Dr. Anil Gokhale, Ulrich Mueller, Mark Neale, Eric Prestemon,
32;; Gary Sabot and Richard Stallman.
33
34;; Maintained (as of version 1.28) by Stephen A. Wood (saw@cebaf.gov)
35
30;;; This version is an update of version 1.21 (Oct 1, 1985). 36;;; This version is an update of version 1.21 (Oct 1, 1985).
31;;; Updated by Stephen A. Wood (saw@hallc1.cebaf.gov) to use tab format 37;;; Updated by Stephen A. Wood (saw@cebaf.gov) to use tab format
32;;; continuation control and indentation. (Digit after TAB to signify 38;;; continuation control and indentation. (Digit after TAB to signify
33;;; continuation line. This version also incorporates suggestions from 39;;; continuation line.
34;;; Richard Stallman, and the ideas in two previous unpublished versions of
35;;; fortran .el (version 1.21.1 (from gildea@expo.lcs.mit.edu) and 1.27
36;;; (prange@erl.mit.edu).)
37 40
38;;; Notes to fortran-mode version 1.28 41;;; Notes to fortran-mode version 1.28
39;;; 1. Fortran mode can support either fixed format or tab format. Fixed 42;;; 1. Fortran mode can support either fixed format or tab format. Fixed
@@ -93,11 +96,50 @@
93;;; you want to use a tab-width other than 8 anyway? 96;;; you want to use a tab-width other than 8 anyway?
94;;; 14. When in tab mode, the fortran column ruler will not be correct if 97;;; 14. When in tab mode, the fortran column ruler will not be correct if
95;;; tab-width is not 8. 98;;; tab-width is not 8.
96 99;;; 15. Fortran-electic-line-number will work properly in overwrite-mode.
97;;; Author acknowledges help from Stephen Gildea <gildea@erl.mit.edu> 100;;; Thanks to Mark Neale (mjn@jet.uk)
101;;; 16. Fixed bug in fortran-previous-statement that gives "Incomplete
102;;; continuation statement." when used on the first statement which
103;;; happens to be a comment that begins with the same character as
104;;; `fortran-continuation-string'
105;;; 17. If `comment-start-skip' is found in a fortran string, no indenting is
106;;; done. Thanks to Ralf Fassel (ralf@up3aud1.gwdg.de) for patches.
107;;; This awaits a hopeful future multimode solution in which
108;;; indentation/spacing inside of constants doesn't get touched when
109;;; comment delimeter characters happen to be inside the constant.
110;;; 18. Changed meaning of `fortran-comment-line-column'. If
111;;; If `fortran-comment-indent-style' is 'fixed, then, comments are
112;;; indented to `fortran-minimum-statement-indent' plus
113;;; `fortran-comment-line-column'. If the style is `relative', the
114;;; meaning remains the same in that the line-column value is added to
115;;; the current indentation level. The default value is now zero.
116;;; (Thanks to Ulrich Mueller (ulm@vsnhd1.cern.ch).
117;;; 19. Fixed infinite loop in fortran-next-statement that occurs with emacs
118;;; versions 18.55 and before because of a difference in the behavior
119;;; of (forward-line 1) on a line that is the last in the buffer which
120;;; doesn't have a newline. (Thanks to Ulrich Mueller)
121;;; 20. Added indentation for structure, union and map blocks (Fortran 90
122;;; and other post f77 fortrans.) at the suggestion of Dr. Anil Gokhale
123;;; (avg@dynsim1.litwin.com).
124;;; 21. The command fortran-auto-fill-mode toggles on and off fortran-auto-fill
125;;; mode. By default it is off, and the fill column is 72. (Thanks to
126;;; (Mark Neale for the code for auto fill.) Will split line before
127;;; whitespace, commas, or operators. Won't break stuff betweek quotes,
128;;; unless it is a comment line. Put (fortran-auto-fill-mode 1) into
129;;; fortran-mode-hook to have auto fill mode automatically on.
130;;; 22. If auto-fill-mode is on, fortran-indent-line will call the auto fill
131;;; code to make sure that lines are not to long after indentation. This
132;;; suggestion and improvements to auto filling provided by Eric Prestemon
133;;; (ecprest@pocorvares.er.usgs.gov.
134;;; 23. comment-line-start-skip treats cpp directives (beginning with #) as
135;;; unindentable comments.
136;;; 24. where, elsewhere indenting now supported for F90.
137;;;
98 138
99;;; Bugs to bug-fortran-mode@erl.mit.edu 139;;; Bugs to bug-fortran-mode@erl.mit.edu
100 140
141(defconst fortran-mode-version "version 1.28.8")
142
101;;; Code: 143;;; Code:
102 144
103;;;###autoload 145;;;###autoload
@@ -117,21 +159,25 @@ with a character in column 6.")
117(defvar fortran-tab-mode-string) 159(defvar fortran-tab-mode-string)
118 160
119(defvar fortran-do-indent 3 161(defvar fortran-do-indent 3
120 "*Extra indentation applied to `do' blocks.") 162 "*Extra indentation applied to DO blocks.")
121 163
122(defvar fortran-if-indent 3 164(defvar fortran-if-indent 3
123 "*Extra indentation applied to `if' blocks.") 165 "*Extra indentation applied to IF blocks.")
166
167(defvar fortran-structure-indent 3
168 "*Extra indentation applied to STRUCTURE, UNION and MAP blocks.")
124 169
125(defvar fortran-continuation-indent 5 170(defvar fortran-continuation-indent 5
126 "*Extra indentation applied to `continuation' lines.") 171 "*Extra indentation applied to Fortran continuation lines.")
127 172
128(defvar fortran-comment-indent-style 'fixed 173(defvar fortran-comment-indent-style 'fixed
129 "*nil forces comment lines not to be touched, 174 "*nil forces comment lines not to be touched,
130'fixed produces fixed comment indentation to comment-column, 175'fixed produces fixed comment indentation to `fortran-comment-line-column'
131and 'relative indents to current fortran indentation plus comment-column.") 176beyond `fortran-minimum-statement-indent', and 'relative indents to current
177Fortran indentation plus `fortran-comment-line-column'.")
132 178
133(defvar fortran-comment-line-column 6 179(defvar fortran-comment-line-column 0
134 "*Indentation for text in comment lines.") 180 "*Amount of extra indentation for text within full-line comments.")
135 181
136(defvar comment-line-start nil 182(defvar comment-line-start nil
137 "*Delimiter inserted to start new full-line comment.") 183 "*Delimiter inserted to start new full-line comment.")
@@ -140,7 +186,7 @@ and 'relative indents to current fortran indentation plus comment-column.")
140 "*Regexp to match the start of a full-line comment.") 186 "*Regexp to match the start of a full-line comment.")
141 187
142(defvar fortran-minimum-statement-indent 6 188(defvar fortran-minimum-statement-indent 6
143 "*Minimum indentation for fortran statements.") 189 "*Minimum indentation for Fortran statements.")
144 190
145;; Note that this is documented in the v18 manuals as being a string 191;; Note that this is documented in the v18 manuals as being a string
146;; of length one rather than a single character. 192;; of length one rather than a single character.
@@ -154,13 +200,13 @@ Normally a space.")
1545 means right-justify them within their five-column field.") 2005 means right-justify them within their five-column field.")
155 201
156(defvar fortran-check-all-num-for-matching-do nil 202(defvar fortran-check-all-num-for-matching-do nil
157 "*Non-nil causes all numbered lines to be treated as possible do-loop ends.") 203 "*Non-nil causes all numbered lines to be treated as possible DO loop ends.")
158 204
159(defvar fortran-blink-matching-if nil 205(defvar fortran-blink-matching-if nil
160 "*From a fortran `endif' statement, blink the matching `if' statement.") 206 "*From a Fortran ENDIF statement, blink the matching IF statement.")
161 207
162(defvar fortran-continuation-string "$" 208(defvar fortran-continuation-string "$"
163 "*Single-character string used for fortran continuation lines. 209 "*Single-character string used for Fortran continuation lines.
164In fixed format continuation style, this character is inserted in 210In fixed format continuation style, this character is inserted in
165column 6 by \\[fortran-split-line] to begin a continuation line. 211column 6 by \\[fortran-split-line] to begin a continuation line.
166Also, if \\[fortran-indent-line] finds this at the beginning of a line, it will 212Also, if \\[fortran-indent-line] finds this at the beginning of a line, it will
@@ -184,8 +230,6 @@ Normally $.")
184(defconst bug-fortran-mode "bug-fortran-mode@erl.mit.edu" 230(defconst bug-fortran-mode "bug-fortran-mode@erl.mit.edu"
185 "Address of mailing list for Fortran mode bugs.") 231 "Address of mailing list for Fortran mode bugs.")
186 232
187(defconst fortran-mode-version "1.28.3")
188
189(defvar fortran-mode-syntax-table nil 233(defvar fortran-mode-syntax-table nil
190 "Syntax table in use in Fortran mode buffers.") 234 "Syntax table in use in Fortran mode buffers.")
191 235
@@ -193,6 +237,9 @@ Normally $.")
193 "Number of lines to scan to determine whether to use fixed or tab format\ 237 "Number of lines to scan to determine whether to use fixed or tab format\
194 style.") 238 style.")
195 239
240(defvar fortran-break-before-delimiters t
241 "*Non-nil causes `fortran-do-auto-fill' to break lines before delimeters.")
242
196(if fortran-mode-syntax-table 243(if fortran-mode-syntax-table
197 () 244 ()
198 (setq fortran-mode-syntax-table (make-syntax-table)) 245 (setq fortran-mode-syntax-table (make-syntax-table))
@@ -207,10 +254,11 @@ Normally $.")
207 (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table) 254 (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table)
208 (modify-syntax-entry ?\\ "/" fortran-mode-syntax-table) 255 (modify-syntax-entry ?\\ "/" fortran-mode-syntax-table)
209 (modify-syntax-entry ?. "w" fortran-mode-syntax-table) 256 (modify-syntax-entry ?. "w" fortran-mode-syntax-table)
257 (modify-syntax-entry ?_ "w" fortran-mode-syntax-table)
210 (modify-syntax-entry ?\n ">" fortran-mode-syntax-table)) 258 (modify-syntax-entry ?\n ">" fortran-mode-syntax-table))
211 259
212(defvar fortran-mode-map () 260(defvar fortran-mode-map ()
213 "Keymap used in fortran mode.") 261 "Keymap used in Fortran mode.")
214(if fortran-mode-map 262(if fortran-mode-map
215 () 263 ()
216 (setq fortran-mode-map (make-sparse-keymap)) 264 (setq fortran-mode-map (make-sparse-keymap))
@@ -246,7 +294,7 @@ Normally $.")
246 (define-abbrev-table 'fortran-mode-abbrev-table ()) 294 (define-abbrev-table 'fortran-mode-abbrev-table ())
247 (define-abbrev fortran-mode-abbrev-table ";au" "automatic" nil) 295 (define-abbrev fortran-mode-abbrev-table ";au" "automatic" nil)
248 (define-abbrev fortran-mode-abbrev-table ";b" "byte" nil) 296 (define-abbrev fortran-mode-abbrev-table ";b" "byte" nil)
249 (define-abbrev fortran-mode-abbrev-table ";bl" "block data" nil) 297 (define-abbrev fortran-mode-abbrev-table ";bd" "block data" nil)
250 (define-abbrev fortran-mode-abbrev-table ";ch" "character" nil) 298 (define-abbrev fortran-mode-abbrev-table ";ch" "character" nil)
251 (define-abbrev fortran-mode-abbrev-table ";cl" "close" nil) 299 (define-abbrev fortran-mode-abbrev-table ";cl" "close" nil)
252 (define-abbrev fortran-mode-abbrev-table ";c" "continue" nil) 300 (define-abbrev fortran-mode-abbrev-table ";c" "continue" nil)
@@ -263,6 +311,7 @@ Normally $.")
263 (define-abbrev fortran-mode-abbrev-table ";el" "elseif" nil) 311 (define-abbrev fortran-mode-abbrev-table ";el" "elseif" nil)
264 (define-abbrev fortran-mode-abbrev-table ";en" "endif" nil) 312 (define-abbrev fortran-mode-abbrev-table ";en" "endif" nil)
265 (define-abbrev fortran-mode-abbrev-table ";eq" "equivalence" nil) 313 (define-abbrev fortran-mode-abbrev-table ";eq" "equivalence" nil)
314 (define-abbrev fortran-mode-abbrev-table ";ew" "endwhere" nil)
266 (define-abbrev fortran-mode-abbrev-table ";ex" "external" nil) 315 (define-abbrev fortran-mode-abbrev-table ";ex" "external" nil)
267 (define-abbrev fortran-mode-abbrev-table ";ey" "entry" nil) 316 (define-abbrev fortran-mode-abbrev-table ";ey" "entry" nil)
268 (define-abbrev fortran-mode-abbrev-table ";f" "format" nil) 317 (define-abbrev fortran-mode-abbrev-table ";f" "format" nil)
@@ -300,15 +349,16 @@ Normally $.")
300 (define-abbrev fortran-mode-abbrev-table ";ty" "type" nil) 349 (define-abbrev fortran-mode-abbrev-table ";ty" "type" nil)
301 (define-abbrev fortran-mode-abbrev-table ";vo" "volatile" nil) 350 (define-abbrev fortran-mode-abbrev-table ";vo" "volatile" nil)
302 (define-abbrev fortran-mode-abbrev-table ";w" "write" nil) 351 (define-abbrev fortran-mode-abbrev-table ";w" "write" nil)
352 (define-abbrev fortran-mode-abbrev-table ";wh" "where" nil)
303 (setq abbrevs-changed ac))) 353 (setq abbrevs-changed ac)))
304 354
305;;;###autoload 355;;;###autoload
306(defun fortran-mode () 356(defun fortran-mode ()
307 "Major mode for editing fortran code. 357 "Major mode for editing Fortran code.
308Tab indents the current fortran line correctly. 358\\[fortran-indent-line] indents the current Fortran line correctly.
309`do' statements must not share a common `continue'. 359DO statements must not share a common CONTINUE.
310 360
311Type `;?' or `;\\[help-command]' to display a list of built-in\ 361Type ;? or ;\\[help-command] to display a list of built-in\
312 abbrevs for Fortran keywords. 362 abbrevs for Fortran keywords.
313 363
314Key definitions: 364Key definitions:
@@ -323,30 +373,33 @@ Variables controlling indentation style and extra features:
323 Extra indentation within do blocks. (default 3) 373 Extra indentation within do blocks. (default 3)
324 fortran-if-indent 374 fortran-if-indent
325 Extra indentation within if blocks. (default 3) 375 Extra indentation within if blocks. (default 3)
376 fortran-structure-indent
377 Extra indentation within structure, union and map blocks. (default 3)
326 fortran-continuation-indent 378 fortran-continuation-indent
327 Extra indentation appled to continuation statements. (default 5) 379 Extra indentation applied to continuation statements. (default 5)
328 fortran-comment-line-column 380 fortran-comment-line-column
329 Amount of indentation for text within full-line comments. (default 6) 381 Amount of extra indentation for text within full-line comments. (default 0)
330 fortran-comment-indent-style 382 fortran-comment-indent-style
331 nil means don't change indentation of text in full-line comments, 383 nil means don't change indentation of text in full-line comments,
332 fixed means indent that text at column fortran-comment-line-column 384 fixed means indent that text at `fortran-comment-line-column' beyond
333 relative means indent at fortran-comment-line-column beyond the 385 the value of `fortran-minimum-statement-indent',
386 relative means indent at `fortran-comment-line-column' beyond the
334 indentation for a line of code. 387 indentation for a line of code.
335 (default 'fixed) 388 (default 'fixed)
336 fortran-comment-indent-char 389 fortran-comment-indent-char
337 Single-character string be inserted instead of space for 390 Single-character string to be inserted instead of space for
338 full-line comment indentation. (default \" \") 391 full-line comment indentation. (default \" \")
339 fortran-minimum-statement-indent 392 fortran-minimum-statement-indent
340 Minimum indentation for fortran statements. (default 6) 393 Minimum indentation for Fortran statements. (default 6)
341 fortran-line-number-indent 394 fortran-line-number-indent
342 Maximum indentation for line numbers. A line number will get 395 Maximum indentation for line numbers. A line number will get
343 less than this much indentation if necessary to avoid reaching 396 less than this much indentation if necessary to avoid reaching
344 column 5. (default 1) 397 column 5. (default 1)
345 fortran-check-all-num-for-matching-do 398 fortran-check-all-num-for-matching-do
346 Non-nil causes all numbered lines to be treated as possible 'continue' 399 Non-nil causes all numbered lines to be treated as possible \"continue\"
347 statements. (default nil) 400 statements. (default nil)
348 fortran-blink-matching-if 401 fortran-blink-matching-if
349 From a fortran `endif' statement, blink the matching `if' statement. 402 From a Fortran ENDIF statement, blink the matching IF statement.
350 (default nil) 403 (default nil)
351 fortran-continuation-string 404 fortran-continuation-string
352 Single-character string to be inserted in column 5 of a continuation 405 Single-character string to be inserted in column 5 of a continuation
@@ -357,26 +410,31 @@ Variables controlling indentation style and extra features:
357 fortran-electric-line-number 410 fortran-electric-line-number
358 Non-nil causes line number digits to be moved to the correct column 411 Non-nil causes line number digits to be moved to the correct column
359 as typed. (default t) 412 as typed. (default t)
413 fortran-break-before-delimiters
414 Non-nil causes `fortran-do-auto-fill' breaks lines before delimeters.
415 (default t)
360 fortran-startup-message 416 fortran-startup-message
361 Set to nil to inhibit message first time Fortran mode is used. 417 Set to nil to inhibit message first time Fortran mode is used.
362 418
363Turning on Fortran mode calls the value of the variable fortran-mode-hook 419Turning on Fortran mode calls the value of the variable `fortran-mode-hook'
364with no args, if that value is non-nil." 420with no args, if that value is non-nil."
365 (interactive) 421 (interactive)
366 (kill-all-local-variables) 422 (kill-all-local-variables)
367 (if fortran-startup-message 423 (if fortran-startup-message
368 (message "Emacs Fortran mode version %s. Bugs to %s" 424 (message "Emacs Fortran mode %s. Bugs to %s"
369 fortran-mode-version bug-fortran-mode)) 425 fortran-mode-version bug-fortran-mode))
370 (setq fortran-startup-message nil) 426 (setq fortran-startup-message nil)
371 (setq local-abbrev-table fortran-mode-abbrev-table) 427 (setq local-abbrev-table fortran-mode-abbrev-table)
372 (set-syntax-table fortran-mode-syntax-table) 428 (set-syntax-table fortran-mode-syntax-table)
429 (make-local-variable 'fortran-break-before-delimiters)
430 (setq fortran-break-before-delimiters t)
373 (make-local-variable 'indent-line-function) 431 (make-local-variable 'indent-line-function)
374 (setq indent-line-function 'fortran-indent-line) 432 (setq indent-line-function 'fortran-indent-line)
375 (make-local-variable 'comment-indent-hook) 433 (make-local-variable 'comment-indent-hook)
376 (setq comment-indent-hook 'fortran-comment-hook) 434 (setq comment-indent-hook 'fortran-comment-hook)
377 (make-local-variable 'comment-line-start-skip) 435 (make-local-variable 'comment-line-start-skip)
378 (setq comment-line-start-skip 436 (setq comment-line-start-skip
379 "^[Cc*]\\(\\([^ \t\n]\\)\\1*\\)?[ \t]*") ;[^ \t\n]* handles c$$$ 437 "^[Cc*]\\(\\([^ \t\n]\\)\\2\\2*\\)?[ \t]*\\|^#.*")
380 (make-local-variable 'comment-line-start) 438 (make-local-variable 'comment-line-start)
381 (setq comment-line-start "c") 439 (setq comment-line-start "c")
382 (make-local-variable 'comment-start-skip) 440 (make-local-variable 'comment-start-skip)
@@ -390,6 +448,7 @@ with no args, if that value is non-nil."
390 (make-local-variable 'indent-tabs-mode) 448 (make-local-variable 'indent-tabs-mode)
391 (setq indent-tabs-mode nil) 449 (setq indent-tabs-mode nil)
392 (setq abbrev-mode t) ; ?? (abbrev-mode 1) instead?? 450 (setq abbrev-mode t) ; ?? (abbrev-mode 1) instead??
451 (setq fill-column 72) ; Already local?
393 (use-local-map fortran-mode-map) 452 (use-local-map fortran-mode-map)
394 (setq mode-name "Fortran") 453 (setq mode-name "Fortran")
395 (setq major-mode 'fortran-mode) 454 (setq major-mode 'fortran-mode)
@@ -419,9 +478,14 @@ or on a new line inserted before this line if this line is not blank."
419 ;; Recognize existing comments of either kind. 478 ;; Recognize existing comments of either kind.
420 (cond ((looking-at comment-line-start-skip) 479 (cond ((looking-at comment-line-start-skip)
421 (fortran-indent-line)) 480 (fortran-indent-line))
422 ((re-search-forward comment-start-skip 481 ((find-comment-start-skip) ; this catches any inline comment and
423 (save-excursion (end-of-line) (point)) t) 482 ; leaves point after comment-start-skip
424 (indent-for-comment)) 483 (if comment-start-skip
484 (progn (goto-char (match-beginning 0))
485 (if (not (= (current-column) (fortran-comment-hook)))
486 (progn (delete-horizontal-space)
487 (indent-to (fortran-comment-hook)))))
488 (end-of-line))) ; otherwise goto end of line or sth else?
425 ;; No existing comment. 489 ;; No existing comment.
426 ;; If side-by-side comments are defined, insert one, 490 ;; If side-by-side comments are defined, insert one,
427 ;; unless line is now blank. 491 ;; unless line is now blank.
@@ -440,7 +504,7 @@ or on a new line inserted before this line if this line is not blank."
440 (insert comment-line-start) 504 (insert comment-line-start)
441 (insert-char (if (stringp fortran-comment-indent-char) 505 (insert-char (if (stringp fortran-comment-indent-char)
442 (aref fortran-comment-indent-char 0) 506 (aref fortran-comment-indent-char 0)
443 fortran-comment-indent-char) 507 fortran-comment-indent-char)
444 (- (calculate-fortran-indent) (current-column)))))) 508 (- (calculate-fortran-indent) (current-column))))))
445 509
446(defun fortran-comment-region (beg-region end-region arg) 510(defun fortran-comment-region (beg-region end-region arg)
@@ -470,7 +534,7 @@ With non-nil ARG, uncomments the region."
470 (set-marker save-point nil))) 534 (set-marker save-point nil)))
471 535
472(defun fortran-abbrev-start () 536(defun fortran-abbrev-start ()
473 "Typing \";\\[help-command]\" or \";?\" lists all the fortran abbrevs. 537 "Typing ;\\[help-command] or ;? lists all the Fortran abbrevs.
474Any other key combination is executed normally." 538Any other key combination is executed normally."
475 (interactive) 539 (interactive)
476 (let (c) 540 (let (c)
@@ -492,7 +556,7 @@ Any other key combination is executed normally."
492 (save-excursion 556 (save-excursion
493 (set-buffer (get-buffer-create "*Abbrevs*")) 557 (set-buffer (get-buffer-create "*Abbrevs*"))
494 (erase-buffer) 558 (erase-buffer)
495 (insert-abbrev-table-description 'fortran-mode-abbrev-table t) 559 (insert-abbrev-table-description fortran-mode-abbrev-table t)
496 (goto-char (point-min)) 560 (goto-char (point-min))
497 (set-buffer-modified-p nil) 561 (set-buffer-modified-p nil)
498 (edit-abbrevs-mode)) 562 (edit-abbrevs-mode))
@@ -504,7 +568,12 @@ The ruler is defined by the value of `fortran-column-ruler'.
504The key typed is executed unless it is SPC." 568The key typed is executed unless it is SPC."
505 (interactive) 569 (interactive)
506 (momentary-string-display 570 (momentary-string-display
507 fortran-column-ruler (save-excursion (beginning-of-line) (point)) 571 fortran-column-ruler (save-excursion
572 (beginning-of-line)
573 (if (eq (window-start (selected-window))
574 (window-point (selected-window)))
575 (progn (forward-line) (point))
576 (point)))
508 nil "Type SPC or any command to erase ruler.")) 577 nil "Type SPC or any command to erase ruler."))
509 578
510(defun fortran-window-create () 579(defun fortran-window-create ()
@@ -521,7 +590,7 @@ See also `fortran-window-create-momentarily'."
521 (other-window 1) 590 (other-window 1)
522 (switch-to-buffer " fortran-window-extra" t) 591 (switch-to-buffer " fortran-window-extra" t)
523 (select-window (previous-window)))) 592 (select-window (previous-window))))
524 (error (message "No room for fortran window.") 593 (error (message "No room for Fortran window.")
525 'error))) 594 'error)))
526 595
527(defun fortran-window-create-momentarily (&optional arg) 596(defun fortran-window-create-momentarily (&optional arg)
@@ -549,8 +618,8 @@ See also `fortran-window-create'."
549 (progn 618 (progn
550 (insert "\n\t") 619 (insert "\n\t")
551 (insert-char (fortran-numerical-continuation-char) 1)) 620 (insert-char (fortran-numerical-continuation-char) 1))
552 (insert "\n" fortran-continuation-string))) 621 (insert "\n " fortran-continuation-string)));Space after \n important
553 (fortran-indent-line)) 622 (fortran-indent-line)) ;when the cont string is C, c or *.
554 623
555(defun fortran-numerical-continuation-char () 624(defun fortran-numerical-continuation-char ()
556 "Return a digit for tab-digit style of continution lines. 625 "Return a digit for tab-digit style of continution lines.
@@ -573,12 +642,10 @@ except that ] is never special and \ quotes ^, - or \."
573(defun fortran-electric-line-number (arg) 642(defun fortran-electric-line-number (arg)
574 "Self insert, but if part of a Fortran line number indent it automatically. 643 "Self insert, but if part of a Fortran line number indent it automatically.
575Auto-indent does not happen if a numeric arg is used." 644Auto-indent does not happen if a numeric arg is used."
576;The use of arg may be superfluous here since there apears to be no way to
577;prefix a digit key with an argument.
578 (interactive "P") 645 (interactive "P")
579 (if (or arg (not fortran-electric-line-number)) 646 (if (or arg (not fortran-electric-line-number))
580 (if arg 647 (if arg
581 (self-insert-command arg) 648 (self-insert-command (prefix-numeric-value arg))
582 (self-insert-command 1)) 649 (self-insert-command 1))
583 (if (or (and (= 5 (current-column)) 650 (if (or (and (= 5 (current-column))
584 (save-excursion 651 (save-excursion
@@ -599,13 +666,13 @@ Auto-indent does not happen if a numeric arg is used."
599 t)) ;not a line number 666 t)) ;not a line number
600 (looking-at "[0-9]") ;within a line number 667 (looking-at "[0-9]") ;within a line number
601 ) 668 )
602 (insert last-command-char) 669 (self-insert-command (prefix-numeric-value arg))
603 (skip-chars-backward " \t") 670 (skip-chars-backward " \t")
604 (insert last-command-char) 671 (insert last-command-char)
605 (fortran-indent-line)))) 672 (fortran-indent-line))))
606 673
607(defun beginning-of-fortran-subprogram () 674(defun beginning-of-fortran-subprogram ()
608 "Moves point to the beginning of the current fortran subprogram." 675 "Moves point to the beginning of the current Fortran subprogram."
609 (interactive) 676 (interactive)
610 (let ((case-fold-search t)) 677 (let ((case-fold-search t))
611 (beginning-of-line -1) 678 (beginning-of-line -1)
@@ -614,7 +681,7 @@ Auto-indent does not happen if a numeric arg is used."
614 (forward-line 1)))) 681 (forward-line 1))))
615 682
616(defun end-of-fortran-subprogram () 683(defun end-of-fortran-subprogram ()
617 "Moves point to the end of the current fortran subprogram." 684 "Moves point to the end of the current Fortran subprogram."
618 (interactive) 685 (interactive)
619 (let ((case-fold-search t)) 686 (let ((case-fold-search t))
620 (beginning-of-line 2) 687 (beginning-of-line 2)
@@ -623,25 +690,27 @@ Auto-indent does not happen if a numeric arg is used."
623 (forward-line 1))) 690 (forward-line 1)))
624 691
625(defun mark-fortran-subprogram () 692(defun mark-fortran-subprogram ()
626 "Put mark at end of fortran subprogram, point at beginning. 693 "Put mark at end of Fortran subprogram, point at beginning.
627The marks are pushed." 694The marks are pushed."
628 (interactive) 695 (interactive)
629 (end-of-fortran-subprogram) 696 (end-of-fortran-subprogram)
630 (push-mark (point)) 697 (push-mark (point))
631 (beginning-of-fortran-subprogram)) 698 (beginning-of-fortran-subprogram))
632 699
633(defun fortran-previous-statement () 700(defun fortran-previous-statement ()
634 "Moves point to beginning of the previous fortran statement. 701 "Moves point to beginning of the previous Fortran statement.
635Returns 'first-statement if that statement is the first 702Returns `first-statement' if that statement is the first
636non-comment Fortran statement in the file, and nil otherwise." 703non-comment Fortran statement in the file, and nil otherwise."
637 (interactive) 704 (interactive)
638 (let (not-first-statement continue-test) 705 (let (not-first-statement continue-test)
639 (beginning-of-line) 706 (beginning-of-line)
640 (setq continue-test 707 (setq continue-test
641 (or (looking-at 708 (and
709 (not (looking-at comment-line-start-skip))
710 (or (looking-at
642 (concat "[ \t]*" (regexp-quote fortran-continuation-string))) 711 (concat "[ \t]*" (regexp-quote fortran-continuation-string)))
643 (or (looking-at " [^ 0\n]") 712 (or (looking-at " [^ 0\n]")
644 (looking-at "\t[1-9]")))) 713 (looking-at "\t[1-9]")))))
645 (while (and (setq not-first-statement (= (forward-line -1) 0)) 714 (while (and (setq not-first-statement (= (forward-line -1) 0))
646 (or (looking-at comment-line-start-skip) 715 (or (looking-at comment-line-start-skip)
647 (looking-at "[ \t]*$") 716 (looking-at "[ \t]*$")
@@ -657,13 +726,15 @@ non-comment Fortran statement in the file, and nil otherwise."
657 'first-statement)))) 726 'first-statement))))
658 727
659(defun fortran-next-statement () 728(defun fortran-next-statement ()
660 "Moves point to beginning of the next fortran statement. 729 "Moves point to beginning of the next Fortran statement.
661Returns `last-statement' if that statement is the last 730Returns `last-statement' if that statement is the last
662non-comment Fortran statement in the file, and nil otherwise." 731non-comment Fortran statement in the file, and nil otherwise."
663 (interactive) 732 (interactive)
664 (let (not-last-statement) 733 (let (not-last-statement)
665 (beginning-of-line) 734 (beginning-of-line)
666 (while (and (setq not-last-statement (= (forward-line 1) 0)) 735 (while (and (setq not-last-statement
736 (and (= (forward-line 1) 0)
737 (not (eobp))))
667 (or (looking-at comment-line-start-skip) 738 (or (looking-at comment-line-start-skip)
668 (looking-at "[ \t]*$") 739 (looking-at "[ \t]*$")
669 (looking-at " [^ 0\n]") 740 (looking-at " [^ 0\n]")
@@ -673,7 +744,7 @@ non-comment Fortran statement in the file, and nil otherwise."
673 'last-statement))) 744 'last-statement)))
674 745
675(defun fortran-blink-matching-if () 746(defun fortran-blink-matching-if ()
676 "From a fortran `endif' statement, blink the matching `if' statement." 747 "From a Fortran ENDIF statement, blink the matching IF statement."
677 (let ((count 1) (top-of-window (window-start)) matching-if 748 (let ((count 1) (top-of-window (window-start)) matching-if
678 (endif-point (point)) message) 749 (endif-point (point)) message)
679 (if (save-excursion (beginning-of-line) 750 (if (save-excursion (beginning-of-line)
@@ -689,21 +760,22 @@ non-comment Fortran statement in the file, and nil otherwise."
689 ; Keep local to subprogram 760 ; Keep local to subprogram
690 (skip-chars-forward " \t0-9") 761 (skip-chars-forward " \t0-9")
691 (cond ((looking-at "if[ \t]*(") 762 (cond ((looking-at "if[ \t]*(")
692 (save-excursion (if (or (looking-at ".*)[ 763 (save-excursion
693\t]*then\\b[ \t]*[^ \t(=a-z0-9]") 764 (if (or
694 (let (then-test);multi-line if-then 765 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
695 (while (and (= (forward-line 1) 0) 766 (let (then-test);multi-line if-then
767 (while
768 (and (= (forward-line 1) 0)
696 ;search forward for then 769 ;search forward for then
697 (or 770 (or (looking-at " [^ 0\n]")
698(looking-at " [^ 0\n]") 771 (looking-at "\t[1-9]"))
699 772 (not
700(looking-at "\t[1-9]")) 773 (setq
701 (not (setq 774 then-test
702then-test (looking-at 775 (looking-at
703 776 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
704 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) 777 then-test))
705 then-test)) 778 (setq count (- count 1)))))
706 (setq count (- count 1)))))
707 ((looking-at "end[ \t]*if\\b") 779 ((looking-at "end[ \t]*if\\b")
708 (setq count (+ count 1))))) 780 (setq count (+ count 1)))))
709 (if (not (= count 0)) 781 (if (not (= count 0))
@@ -716,13 +788,13 @@ then-test (looking-at
716 (point))))) 788 (point)))))
717 (setq matching-if (point))))) 789 (setq matching-if (point)))))
718 (if message 790 (if message
719 (message message) 791 (message "%s" message)
720 (goto-char matching-if) 792 (goto-char matching-if)
721 (sit-for 1) 793 (sit-for 1)
722 (goto-char endif-point)))))) 794 (goto-char endif-point))))))
723 795
724(defun fortran-indent-line () 796(defun fortran-indent-line ()
725 "Indents current fortran line based on its contents and on previous lines." 797 "Indents current Fortran line based on its contents and on previous lines."
726 (interactive) 798 (interactive)
727 (let ((cfi (calculate-fortran-indent))) 799 (let ((cfi (calculate-fortran-indent)))
728 (save-excursion 800 (save-excursion
@@ -733,18 +805,22 @@ then-test (looking-at
733 (fortran-indent-to-column cfi) 805 (fortran-indent-to-column cfi)
734 (beginning-of-line) 806 (beginning-of-line)
735 (if (and (not (looking-at comment-line-start-skip)) 807 (if (and (not (looking-at comment-line-start-skip))
736 (re-search-forward comment-start-skip 808 (find-comment-start-skip))
737 (save-excursion (end-of-line) (point)) 'move))
738 (fortran-indent-comment)))) 809 (fortran-indent-comment))))
739 ;; Never leave point in left margin. 810 ;; Never leave point in left margin.
740 (if (< (current-column) cfi) 811 (if (< (current-column) cfi)
741 (move-to-column cfi)) 812 (move-to-column cfi))
813 (if (and auto-fill-hook
814 (> (save-excursion (end-of-line) (current-column)) fill-column))
815 (save-excursion
816 (end-of-line)
817 (fortran-do-auto-fill)))
742 (if fortran-blink-matching-if 818 (if fortran-blink-matching-if
743 (fortran-blink-matching-if)))) 819 (fortran-blink-matching-if))))
744 820
745(defun fortran-reindent-then-newline-and-indent () 821(defun fortran-reindent-then-newline-and-indent ()
746 "Reindent the current fortran line, insert a newline and indent the newline. 822 "Reindent the current Fortran line, insert a newline and indent the newline.
747An abbrev before point is expanded if abbrev-mode is non-nil." 823An abbrev before point is expanded if `abbrev-mode' is non-nil."
748 (interactive) 824 (interactive)
749 (if abbrev-mode (expand-abbrev)) 825 (if abbrev-mode (expand-abbrev))
750 (save-excursion 826 (save-excursion
@@ -755,9 +831,9 @@ An abbrev before point is expanded if abbrev-mode is non-nil."
755 (looking-at "else") 831 (looking-at "else")
756 (looking-at (regexp-quote fortran-continuation-string))) 832 (looking-at (regexp-quote fortran-continuation-string)))
757 (fortran-indent-line))) 833 (fortran-indent-line)))
758 (insert "\n") 834 (newline)
759 (fortran-indent-line)) 835 (fortran-indent-line))
760 836
761(defun fortran-indent-subprogram () 837(defun fortran-indent-subprogram ()
762 "Properly indents the Fortran subprogram which contains point." 838 "Properly indents the Fortran subprogram which contains point."
763 (interactive) 839 (interactive)
@@ -768,7 +844,7 @@ An abbrev before point is expanded if abbrev-mode is non-nil."
768 (message "Indenting subprogram...done.")) 844 (message "Indenting subprogram...done."))
769 845
770(defun calculate-fortran-indent () 846(defun calculate-fortran-indent ()
771 "Calculates the fortran indent column based on previous lines." 847 "Calculates the Fortran indent column based on previous lines."
772 (let (icol first-statement (case-fold-search t) 848 (let (icol first-statement (case-fold-search t)
773 (fortran-minimum-statement-indent 849 (fortran-minimum-statement-indent
774 fortran-minimum-statement-indent)) 850 fortran-minimum-statement-indent))
@@ -782,34 +858,44 @@ An abbrev before point is expanded if abbrev-mode is non-nil."
782 (setq icol (fortran-current-line-indentation))) 858 (setq icol (fortran-current-line-indentation)))
783 (skip-chars-forward " \t0-9") 859 (skip-chars-forward " \t0-9")
784 (cond ((looking-at "if[ \t]*(") 860 (cond ((looking-at "if[ \t]*(")
785 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") 861 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]")
786 (let (then-test) ;multi-line if-then 862 (let (then-test) ;multi-line if-then
787 (while (and (= (forward-line 1) 0) 863 (while (and (= (forward-line 1) 0)
788 ;search forward for then 864 ;;search forward for then
789 (or (looking-at " [^ 0\n]") 865 (or (looking-at " [^ 0\n]")
790 (looking-at "\t[1-9]")) 866 (looking-at "\t[1-9]"))
791 (not (setq then-test (looking-at 867 (not (setq then-test (looking-at
792 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) 868 ".*then\\b[ \t]\
869*[^ \t_$(=a-z0-9]")))))
793 then-test)) 870 then-test))
794 (setq icol (+ icol fortran-if-indent)))) 871 (setq icol (+ icol fortran-if-indent))))
795 ((looking-at "\\(else\\|elseif\\)\\b") 872 ((looking-at "\\(else\\|elseif\\)\\b")
796 (setq icol (+ icol fortran-if-indent))) 873 (setq icol (+ icol fortran-if-indent)))
874 ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
875 (setq icol (+ icol fortran-if-indent)))
876 ((looking-at "where.*(.*)[ \t]*\n")
877 (setq icol (+ icol fortran-if-indent)))
797 ((looking-at "do\\b") 878 ((looking-at "do\\b")
798 (setq icol (+ icol fortran-do-indent))) 879 (setq icol (+ icol fortran-do-indent)))
880 ((looking-at
881 "\\(structure\\|union\\|map\\)\\b[ \t]*[^ \t=(a-z]")
882 (setq icol (+ icol fortran-structure-indent)))
799 ((looking-at "end\\b[ \t]*[^ \t=(a-z]") 883 ((looking-at "end\\b[ \t]*[^ \t=(a-z]")
800 ; Previous END resets indent to minimum 884 ;; Previous END resets indent to minimum
801 (setq icol fortran-minimum-statement-indent)))))) 885 (setq icol fortran-minimum-statement-indent))))))
802 (save-excursion 886 (save-excursion
803 (beginning-of-line) 887 (beginning-of-line)
804 (cond ((looking-at "[ \t]*$")) 888 (cond ((looking-at "[ \t]*$"))
805 ((looking-at comment-line-start-skip) 889 ((looking-at comment-line-start-skip)
806 (setq fortran-minimum-statement-indent 0)
807 (cond ((eq fortran-comment-indent-style 'relative) 890 (cond ((eq fortran-comment-indent-style 'relative)
808 (setq icol (+ icol fortran-comment-line-column))) 891 (setq icol (+ icol fortran-comment-line-column)))
809 ((eq fortran-comment-indent-style 'fixed) 892 ((eq fortran-comment-indent-style 'fixed)
810 (setq icol fortran-comment-line-column)))) 893 (setq icol (+ fortran-minimum-statement-indent
894 fortran-comment-line-column))))
895 (setq fortran-minimum-statement-indent 0))
811 ((or (looking-at (concat "[ \t]*" 896 ((or (looking-at (concat "[ \t]*"
812 (regexp-quote fortran-continuation-string))) 897 (regexp-quote
898 fortran-continuation-string)))
813 (looking-at " [^ 0\n]") 899 (looking-at " [^ 0\n]")
814 (looking-at "\t[1-9]")) 900 (looking-at "\t[1-9]"))
815 (setq icol (+ icol fortran-continuation-indent))) 901 (setq icol (+ icol fortran-continuation-indent)))
@@ -824,11 +910,19 @@ An abbrev before point is expanded if abbrev-mode is non-nil."
824 (setq icol (- icol fortran-if-indent))) 910 (setq icol (- icol fortran-if-indent)))
825 ((looking-at "\\(else\\|elseif\\)\\b") 911 ((looking-at "\\(else\\|elseif\\)\\b")
826 (setq icol (- icol fortran-if-indent))) 912 (setq icol (- icol fortran-if-indent)))
913 ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
914 (setq icol (- icol fortran-if-indent)))
915 ((looking-at "end[ \t]*where\\b")
916 (setq icol (- icol fortran-if-indent)))
827 ((and (looking-at "continue\\b") 917 ((and (looking-at "continue\\b")
828 (fortran-check-for-matching-do)) 918 (fortran-check-for-matching-do))
829 (setq icol (- icol fortran-do-indent))) 919 (setq icol (- icol fortran-do-indent)))
830 ((looking-at "end[ \t]*do\\b") 920 ((looking-at "end[ \t]*do\\b")
831 (setq icol (- icol fortran-do-indent))) 921 (setq icol (- icol fortran-do-indent)))
922 ((looking-at
923 "end[ \t]*\
924\\(structure\\|union\\|map\\)\\b[ \t]*[^ \t=(a-z]")
925 (setq icol (- icol fortran-structure-indent)))
832 ((and (looking-at "end\\b[ \t]*[^ \t=(a-z]") 926 ((and (looking-at "end\\b[ \t]*[^ \t=(a-z]")
833 (not (= icol fortran-minimum-statement-indent))) 927 (not (= icol fortran-minimum-statement-indent)))
834 (message "Warning: `end' not in column %d. Probably\ 928 (message "Warning: `end' not in column %d. Probably\
@@ -846,15 +940,16 @@ non-indentation text within the comment."
846 (cond ((looking-at comment-line-start-skip) 940 (cond ((looking-at comment-line-start-skip)
847 (goto-char (match-end 0)) 941 (goto-char (match-end 0))
848 (skip-chars-forward 942 (skip-chars-forward
849 (if (stringp fortran-comment-indent-char) 943 (if (stringp fortran-comment-indent-char)
850 fortran-comment-indent-char 944 fortran-comment-indent-char
851 (char-to-string fortran-comment-indent-char)))) 945 (char-to-string fortran-comment-indent-char))))
852 ((or (looking-at " [^ 0\n]") 946 ((or (looking-at " [^ 0\n]")
853 (looking-at "\t[1-9]")) 947 (looking-at "\t[1-9]"))
854 (goto-char (match-end 0))) 948 (goto-char (match-end 0)))
855 (t 949 (t
856 ;; Move past line number. 950 ;; Move past line number.
857 (re-search-forward "^[ \t0-9]*" (+ (point) 4) t))) 951 (skip-chars-forward "[ \t0-9]");From Uli
952 ))
858 ;; Move past whitespace. 953 ;; Move past whitespace.
859 (skip-chars-forward " \t") 954 (skip-chars-forward " \t")
860 (current-column))) 955 (current-column)))
@@ -863,18 +958,18 @@ non-indentation text within the comment."
863 "Indents current line with spaces to column COL. 958 "Indents current line with spaces to column COL.
864notes: 1) A non-zero/non-blank character in column 5 indicates a continuation 959notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
865 line, and this continuation character is retained on indentation; 960 line, and this continuation character is retained on indentation;
866 2) If fortran-continuation-string is the first non-whitespace character, 961 2) If `fortran-continuation-string' is the first non-whitespace
867 this is a continuation line; 962 character, this is a continuation line;
868 3) A non-continuation line which has a number as the first 963 3) A non-continuation line which has a number as the first
869 non-whitespace character is a numbered line. 964 non-whitespace character is a numbered line.
870 4) A tab followed by a digit indicates a continuation line." 965 4) A TAB followed by a digit indicates a continuation line."
871 (save-excursion 966 (save-excursion
872 (beginning-of-line) 967 (beginning-of-line)
873 (if (looking-at comment-line-start-skip) 968 (if (looking-at comment-line-start-skip)
874 (if fortran-comment-indent-style 969 (if fortran-comment-indent-style
875 (let ((char (if (stringp fortran-comment-indent-char) 970 (let ((char (if (stringp fortran-comment-indent-char)
876 (aref fortran-comment-indent-char 0) 971 (aref fortran-comment-indent-char 0)
877 fortran-comment-indent-char))) 972 fortran-comment-indent-char)))
878 (goto-char (match-end 0)) 973 (goto-char (match-end 0))
879 (delete-horizontal-regexp (concat " \t" (char-to-string char))) 974 (delete-horizontal-regexp (concat " \t" (char-to-string char)))
880 (insert-char char (- col (current-column))))) 975 (insert-char char (- col (current-column)))))
@@ -891,8 +986,8 @@ notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
891 (insert-char (fortran-numerical-continuation-char) 1)) 986 (insert-char (fortran-numerical-continuation-char) 1))
892 (forward-char 6)) 987 (forward-char 6))
893 (delete-horizontal-space) 988 (delete-horizontal-space)
894 ;; Put line number in columns 0-4 989 ;; Put line number in columns 0-4
895 ;; or put continuation character in column 5. 990 ;; or put continuation character in column 5.
896 (cond ((eobp)) 991 (cond ((eobp))
897 ((looking-at (regexp-quote fortran-continuation-string)) 992 ((looking-at (regexp-quote fortran-continuation-string))
898 (if fortran-tab-mode 993 (if fortran-tab-mode
@@ -900,8 +995,8 @@ notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
900 (indent-to fortran-minimum-statement-indent) 995 (indent-to fortran-minimum-statement-indent)
901 (delete-char 1) 996 (delete-char 1)
902 (insert-char (fortran-numerical-continuation-char) 1)) 997 (insert-char (fortran-numerical-continuation-char) 1))
903 (indent-to 5)) 998 (indent-to 5)
904 (forward-char 1)) 999 (forward-char 1)))
905 ((looking-at "[0-9]+") 1000 ((looking-at "[0-9]+")
906 (let ((extra-space (- 5 (- (match-end 0) (point))))) 1001 (let ((extra-space (- 5 (- (match-end 0) (point)))))
907 (if (< extra-space 0) 1002 (if (< extra-space 0)
@@ -914,8 +1009,7 @@ notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
914 (indent-to col) 1009 (indent-to col)
915 ;; Indent any comment following code on the same line. 1010 ;; Indent any comment following code on the same line.
916 (if (and comment-start-skip 1011 (if (and comment-start-skip
917 (re-search-forward comment-start-skip 1012 (find-comment-start-skip))
918 (save-excursion (end-of-line) (point)) t))
919 (progn (goto-char (match-beginning 0)) 1013 (progn (goto-char (match-beginning 0))
920 (if (not (= (current-column) (fortran-comment-hook))) 1014 (if (not (= (current-column) (fortran-comment-hook)))
921 (progn (delete-horizontal-space) 1015 (progn (delete-horizontal-space)
@@ -933,7 +1027,7 @@ Do not call if there is no line number."
933 (= (current-column) 5)))))) 1027 (= (current-column) 5))))))
934 1028
935(defun fortran-check-for-matching-do () 1029(defun fortran-check-for-matching-do ()
936 "When called from a numbered statement, returns t if matching 'do' is found. 1030 "When called from a numbered statement, returns t if matching DO is found.
937Otherwise return a nil." 1031Otherwise return a nil."
938 (let (charnum 1032 (let (charnum
939 (case-fold-search t)) 1033 (case-fold-search t))
@@ -949,8 +1043,9 @@ Otherwise return a nil."
949 (beginning-of-line) 1043 (beginning-of-line)
950 (and (re-search-backward 1044 (and (re-search-backward
951 (concat 1045 (concat
952 "\\(^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]\\)\\|\\(^[ \t0-9]*do[ \t]*0*" 1046 "\\(^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]\\)\\|\\(^[ \t0-9]*do\
953 charnum "\\b\\)\\|\\(^[ \t]*0*" charnum "\\b\\)") 1047[ \t]*0*"
1048 charnum "\\b\\)\\|\\(^[ \t]*0*" charnum "\\b\\)")
954 nil t) 1049 nil t)
955 (looking-at (concat "^[ \t0-9]*do[ \t]*0*" charnum)))))))) 1050 (looking-at (concat "^[ \t0-9]*do[ \t]*0*" charnum))))))))
956 1051
@@ -961,6 +1056,7 @@ file before the end or the first `fortran-analyze-depth' lines."
961 (let ((i 0)) 1056 (let ((i 0))
962 (save-excursion 1057 (save-excursion
963 (goto-char (point-min)) 1058 (goto-char (point-min))
1059 (setq i 0)
964 (while (not (or 1060 (while (not (or
965 (eobp) 1061 (eobp)
966 (looking-at "\t") 1062 (looking-at "\t")
@@ -991,37 +1087,220 @@ If argument is a positive number, or non-nil if not a number,
991 (set-buffer-modified-p (buffer-modified-p))) ;No-op, but updates mode line. 1087 (set-buffer-modified-p (buffer-modified-p))) ;No-op, but updates mode line.
992 1088
993(defun fortran-setup-tab-format-style () 1089(defun fortran-setup-tab-format-style ()
994 "Set up fortran mode to use the TAB-digit mode of continuation lines. 1090 "Set up Fortran mode to use the TAB-digit mode of continuation lines.
995Use the command fortran-tab-mode to toggle between this and fixed format style." 1091Use the command `fortran-tab-mode' to toggle between this and fixed
996 (setq fortran-comment-line-column (max tab-width 6)) 1092format style."
997 (setq fortran-minimum-statement-indent (max tab-width 6)) 1093 (setq fortran-minimum-statement-indent (max tab-width 6))
998 (setq indent-tabs-mode t) 1094 (setq indent-tabs-mode t)
999 (setq fortran-column-ruler 1095 (setq fortran-column-ruler
1000 (concat 1096 (concat
1001 "0 810 20 30 40 50 60 70\n" 1097 "0 810 20 30 40 5\
1002 "[ ]| { | | | | | | | | | | | | |}\n")) 10980 60 70\n"
1099 "[ ]| { | | | | | | | | \
1100| | | | |}\n"))
1003 (setq fortran-tab-mode-string " TAB-format") 1101 (setq fortran-tab-mode-string " TAB-format")
1004 (set-buffer-modified-p (buffer-modified-p))) 1102 (set-buffer-modified-p (buffer-modified-p)))
1005 1103
1006(defun fortran-setup-fixed-format-style () 1104(defun fortran-setup-fixed-format-style ()
1007 "Set up fortran mode to use the column 6 mode of continuation lines. 1105 "Set up Fortran mode to use the column 6 mode of continuation lines.
1008Use the command `fortran-tab-mode' to toggle between this and tab 1106Use the command `fortran-tab-mode' to toggle between this and tab
1009character format style." 1107character format style."
1010 (setq fortran-comment-line-column 6)
1011 (setq fortran-minimum-statement-indent 6) 1108 (setq fortran-minimum-statement-indent 6)
1012 (setq indent-tabs-mode nil) 1109 (setq indent-tabs-mode nil)
1013 (setq fortran-column-ruler 1110 (setq fortran-column-ruler
1014 (concat 1111 (concat
1015 "0 4 6 10 20 30 40 50 60 70\n" 1112 "0 4 6 10 20 30 40 5\
1016 "[ ]|{ | | | | | | | | | | | | |}\n")) 11130 60 70\n"
1114 "[ ]|{ | | | | | | | | \
1115| | | | |}\n"))
1017 (setq fortran-tab-mode-string " Fixed-format") 1116 (setq fortran-tab-mode-string " Fixed-format")
1018 (set-buffer-modified-p (buffer-modified-p))) 1117 (set-buffer-modified-p (buffer-modified-p)))
1019 1118
1020(or (assq 'fortran-tab-mode minor-mode-alist) 1119(or (assq 'fortran-tab-mode-string minor-mode-alist)
1021 (setq minor-mode-alist (cons 1120 (setq minor-mode-alist (cons
1022 '(fortran-tab-mode-string fortran-tab-mode-string) 1121 '(fortran-tab-mode-string fortran-tab-mode-string)
1023 minor-mode-alist))) 1122 minor-mode-alist)))
1024 1123
1124(defun find-comment-start-skip ()
1125 "Move to past `comment-start-skip' found on current line.
1126Return t if `comment-start-skip' found, nil if not."
1127;;; In order to move point only if comment-start-skip is found,
1128;;; this one uses a lot of save-excursions. Note that re-search-forward
1129;;; moves point even if comment-start-skip is inside a string-constant.
1130;;; Some code expects certain values for match-beginning and end
1131 (interactive)
1132 (let ((save-match-beginning) (save-match-end))
1133 (if (save-excursion
1134 (re-search-forward comment-start-skip
1135 (save-excursion (end-of-line) (point)) t))
1136 (progn
1137 (setq save-match-beginning (match-beginning 0))
1138 (setq save-match-end (match-end 0))
1139 (if (is-in-fortran-string-p (match-beginning 0))
1140 (progn
1141 (save-excursion
1142 (goto-char save-match-end)
1143 (find-comment-start-skip)) ; recurse for rest of line
1144 )
1145 (goto-char save-match-beginning)
1146 (re-search-forward comment-start-skip
1147 (save-excursion (end-of-line) (point)) t)
1148 (goto-char (match-end 0))
1149 t))
1150 nil)))
1151
1152(defun is-in-fortran-string-p (pos)
1153 "Return t if POS (a buffer position) is inside a standard Fortran string.
1154Fortran strings are delimeted by apostrophes (\'). Quote-Escape-sequences
1155(\\'), strings delimited by \" and detection of syntax-errors
1156(unbalanced quotes) are NOT supported."
1157;;; The algorithm is simple: start at point with value nil
1158;;; and toggle value at each quote found until end of line.
1159;;; The quote skip is hard-coded, maybe it's possible to change this
1160;;; and use something like 'string-constant-delimiter' (which
1161;;; doesn't exist yet) so this function can be used by other modes,
1162;;; but then one must pay attention to escape sequences, multi-line-constants
1163;;; and such things.
1164 (let ((is-in-fortran-string nil))
1165 (save-excursion
1166 (goto-char pos)
1167 (fortran-previous-statement)
1168 (fortran-next-statement)
1169 (while (< (point) pos)
1170 ;; Make sure we don't count quotes in continuation column.
1171 (if (looking-at "^ ")
1172 (goto-char (+ 1 (match-end 0)))
1173 (if (and (not is-in-fortran-string)
1174 (looking-at comment-start-skip))
1175 (beginning-of-line 2)
1176 (if (looking-at "'")
1177 (setq is-in-fortran-string (not is-in-fortran-string)))
1178 (forward-char 1)))))
1179 is-in-fortran-string))
1180
1181(defun fortran-auto-fill-mode (arg)
1182 "Toggle fortran-auto-fill mode.
1183With ARG, turn `fortran-auto-fill' mode on iff ARG is positive.
1184In `fortran-auto-fill' mode, inserting a space at a column beyond `fill-column'
1185automatically breaks the line at a previous space."
1186 (interactive "P")
1187 (prog1 (setq auto-fill-hook
1188 (if (if (null arg)
1189 (not auto-fill-hook)
1190 (> (prefix-numeric-value arg) 0))
1191 'fortran-indent-line
1192 nil))
1193 ;; update mode-line
1194 (set-buffer-modified-p (buffer-modified-p))))
1195
1196(defun fortran-do-auto-fill ()
1197 (interactive)
1198 (let* ((opoint (point))
1199 (bol (save-excursion (beginning-of-line) (point)))
1200 (eol (save-excursion (end-of-line) (point)))
1201 (bos (min eol (+ bol (fortran-current-line-indentation))))
1202 (quote
1203 (save-excursion
1204 (goto-char bol)
1205 (if (looking-at comment-line-start-skip)
1206 nil ; OK to break quotes on comment lines.
1207 (move-to-column fill-column)
1208 (cond ((is-in-fortran-string-p (point))
1209 (save-excursion (re-search-backward "[^']'[^']" bol t)
1210 (if fortran-break-before-delimiters
1211 (point)
1212 (1+ (point)))))
1213 (t nil)))))
1214 ;;
1215 ;; decide where to split the line. If a position for a quoted
1216 ;; string was found above then use that, else break the line
1217 ;; before the last delimiter.
1218 ;; Delimeters are whitespace, commas, and operators.
1219 ;; Will break before a pair of *'s.
1220 ;;
1221 (fill-point
1222 (or quote
1223 (save-excursion
1224 (move-to-column (1+ fill-column))
1225 (skip-chars-backward "^ \t\n,'+-/*=)"
1226;;; (if fortran-break-before-delimiters
1227;;; "^ \t\n,'+-/*=" "^ \t\n,'+-/*=)")
1228 )
1229 (if (<= (point) (1+ bos))
1230 (progn
1231 (move-to-column (1+ fill-column))
1232 (if (not (re-search-forward "[\t\n,'+-/*)=]" eol t))
1233 (goto-char bol))))
1234 (if (bolp)
1235 (re-search-forward "[ \t]" opoint t)
1236 (forward-char -1)
1237 (if (looking-at "'")
1238 (forward-char 1)
1239 (skip-chars-backward " \t\*")))
1240 (if fortran-break-before-delimiters
1241 (point)
1242 (1+ (point))))))
1243 )
1244 ;; if we are in an in-line comment, don't break unless the
1245 ;; line of code is longer than it should be. Otherwise
1246 ;; break the line at the column computed above.
1247 ;;
1248 ;; Need to use find-comment-start-skip to make sure that quoted !'s
1249 ;; don't prevent a break.
1250 (if (not (or (save-excursion
1251 (if (and (re-search-backward comment-start-skip bol t)
1252 (not (is-in-fortran-string-p (point))))
1253 (progn
1254 (skip-chars-backward " \t")
1255 (< (current-column) (1+ fill-column)))))
1256 (save-excursion
1257 (goto-char fill-point)
1258 (bolp))))
1259 (if (> (save-excursion
1260 (goto-char fill-point) (current-column))
1261 (1+ fill-column))
1262 (progn (goto-char fill-point)
1263 (fortran-break-line))
1264 (save-excursion
1265 (if (> (save-excursion
1266 (goto-char fill-point)
1267 (current-column))
1268 (+ (calculate-fortran-indent) fortran-continuation-indent))
1269 (progn
1270 (goto-char fill-point)
1271 (fortran-break-line))))))
1272 ))
1273(defun fortran-break-line ()
1274 (let ((opoint (point))
1275 (bol (save-excursion (beginning-of-line) (point)))
1276 (eol (save-excursion (end-of-line) (point)))
1277 (comment-string nil))
1278
1279 (save-excursion
1280 (if (and comment-start-skip (find-comment-start-skip))
1281 (progn
1282 (re-search-backward comment-start-skip bol t)
1283 (setq comment-string (buffer-substring (point) eol))
1284 (delete-region (point) eol))))
1285;;; Forward line 1 really needs to go to next non white line
1286 (if (save-excursion (forward-line 1)
1287 (or (looking-at " [^ 0\n]")
1288 (looking-at "\t[1-9]")))
1289 (progn
1290 (forward-line 1)
1291 (delete-indentation)
1292 (delete-char 2)
1293 (delete-horizontal-space)
1294 (fortran-do-auto-fill))
1295 (fortran-split-line))
1296 (if comment-string
1297 (save-excursion
1298 (goto-char bol)
1299 (end-of-line)
1300 (delete-horizontal-space)
1301 (indent-to (fortran-comment-hook))
1302 (insert comment-string)))))
1303
1025(provide 'fortran) 1304(provide 'fortran)
1026 1305
1027;;; fortran.el ends here 1306;;; fortran.el ends here