comparison lisp/progmodes/fortran.el @ 26560:edf06ac56d1f

(fortran-comment-line-start): Renamed from comment-line-start. (fortran-comment-line-start-skip): Renamed from comment-line-start-skip. (fortran-mode-map): Use renamed functions. Add manual and custom entries to menu. (fortran-mode-hook): Customize. (fortran-comment-indent-function): Renamed from fortran-comment-hook. (delete-horizontal-regexp): Function deleted. (fortran-electric-line-number): Simplified. (fortran-beginning-of-subprogram): Renamed from beginning-of-fortran-subprogram. (fortran-end-of-subprogram): Renamed from end-of-fortran-subprogram. (fortran-mark-subprogram): Renamed from mark-fortran-subprogram. (fortran-previous-statement, fortran-next-statement): Simplified. (fortran-blink-match): New function. (fortran-blink-matching-if, fortran-blink-matching-do): Use it. (fortran-indent-to-column): Don't use delete-horizontal-regexp. (fortran-find-comment-start-skip, fortran-is-in-string-p): Use line-end-position. (fortran-fill): No longer interactive. Simplified. (fortran-break-line): Simplified. (fortran-analyze-file-format): Use char-after, not looking-at.
author Dave Love <fx@gnu.org>
date Tue, 23 Nov 1999 20:19:47 +0000
parents ec613559ec18
children 4aede027bedb
comparison
equal deleted inserted replaced
26559:13f0cb9be0ca 26560:edf06ac56d1f
42 42
43 ;;; Code: 43 ;;; Code:
44 44
45 ;; Todo: 45 ;; Todo:
46 46
47 ;; * Tidy it all up! (including renaming non-`fortran' prefixed 47 ;; * Tidy it all up!
48 ;; functions).
49 ;; * Implement insertion and removal of statement continuations in 48 ;; * Implement insertion and removal of statement continuations in
50 ;; mixed f77/f90 style, with the first `&' past column 72 and the 49 ;; mixed f77/f90 style, with the first `&' past column 72 and the
51 ;; second in column 6. 50 ;; second in column 6.
52 ;; * Support any other extensions to f77 grokked by GNU Fortran. 51 ;; * Support any other extensions to f77 grokked by GNU Fortran.
53 ;; * Change fontification to use font-lock-syntactic-keywords for
54 ;; fixed-form comments. (Done, but doesn't work properly with
55 ;; lazy-lock in pre-20.4.)
56 52
57 (require 'easymenu) 53 (require 'easymenu)
58 54
59 (defgroup fortran nil 55 (defgroup fortran nil
60 "Fortran mode for Emacs" 56 "Fortran mode for Emacs"
123 "*Amount of extra indentation for text within full-line comments." 119 "*Amount of extra indentation for text within full-line comments."
124 :type 'integer 120 :type 'integer
125 :group 'fortran-indent 121 :group 'fortran-indent
126 :group 'fortran-comment) 122 :group 'fortran-comment)
127 123
128 (defcustom comment-line-start nil 124 (defcustom fortran-comment-line-start nil
129 "*Delimiter inserted to start new full-line comment." 125 "*Delimiter inserted to start new full-line comment."
126 :version "21.1"
130 :type '(choice string (const nil)) 127 :type '(choice string (const nil))
131 :group 'fortran-comment) 128 :group 'fortran-comment)
132 129
133 (defcustom comment-line-start-skip nil 130 (defcustom fortran-comment-line-start-skip nil
134 "*Regexp to match the start of a full-line comment." 131 "*Regexp to match the start of a full-line comment."
132 :version "21.1"
135 :type '(choice string (const nil)) 133 :type '(choice string (const nil))
136 :group 'fortran-comment) 134 :group 'fortran-comment)
137 135
138 (defcustom fortran-minimum-statement-indent-fixed 6 136 (defcustom fortran-minimum-statement-indent-fixed 6
139 "*Minimum statement indentation for fixed format continuation style." 137 "*Minimum statement indentation for fixed format continuation style."
299 "format" "print" "select" "case" "cycle" "exit")))) 297 "format" "print" "select" "case" "cycle" "exit"))))
300 (fortran-logicals 298 (fortran-logicals
301 (eval-when-compile 299 (eval-when-compile
302 (regexp-opt '("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne" 300 (regexp-opt '("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne"
303 "true" "false"))))) 301 "true" "false")))))
304
305 (setq fortran-font-lock-syntactic-keywords 302 (setq fortran-font-lock-syntactic-keywords
306 ;; Fixed format comments. (!-style handled normally.) 303 ;; Fixed format comments. (!-style handled normally.)
307 (list 304 (list
308 (list (concat "^[" comment-chars "]") 0 '(11)) 305 (list (concat "^[" comment-chars "]") 0 '(11))
309 (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.) 306 (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.)
310 "\\([^\n]+\\)") 307 "\\([^\n]+\\)")
311 1 '(11)))) 308 1 '(11))))
312
313 (setq fortran-font-lock-keywords-1 309 (setq fortran-font-lock-keywords-1
314 (list 310 (list
315 ;;
316 ;; Program, subroutine and function declarations, plus calls. 311 ;; Program, subroutine and function declarations, plus calls.
317 (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|" 312 (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|"
318 "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?") 313 "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?")
319 '(1 font-lock-keyword-face) 314 '(1 font-lock-keyword-face)
320 '(2 font-lock-function-name-face nil t)))) 315 '(2 font-lock-function-name-face nil t))))
321
322 (setq fortran-font-lock-keywords-2 316 (setq fortran-font-lock-keywords-2
323 (append fortran-font-lock-keywords-1 317 (append fortran-font-lock-keywords-1
324 (list 318 (list
325 ;;
326 ;; Fontify all type specifiers (must be first; see below). 319 ;; Fontify all type specifiers (must be first; see below).
327 (cons (concat "\\<\\(" fortran-type-types "\\)\\>") 320 (cons (concat "\\<\\(" fortran-type-types "\\)\\>")
328 'font-lock-type-face) 321 'font-lock-type-face)
329 ;;
330 ;; Fontify all builtin keywords (except logical, do 322 ;; Fontify all builtin keywords (except logical, do
331 ;; and goto; see below). 323 ;; and goto; see below).
332 (concat "\\<\\(" fortran-keywords "\\)\\>") 324 (concat "\\<\\(" fortran-keywords "\\)\\>")
333 ;;
334 ;; Fontify all builtin operators. 325 ;; Fontify all builtin operators.
335 (concat "\\.\\(" fortran-logicals "\\)\\.") 326 (concat "\\.\\(" fortran-logicals "\\)\\.")
336 ;;
337 ;; Fontify do/goto keywords and targets, and goto tags. 327 ;; Fontify do/goto keywords and targets, and goto tags.
338 (list "\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?" 328 (list "\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?"
339 '(1 font-lock-keyword-face) 329 '(1 font-lock-keyword-face)
340 '(2 font-lock-constant-face nil t)) 330 '(2 font-lock-constant-face nil t))
341 (cons "^ *\\([0-9]+\\)" 'font-lock-constant-face)))) 331 (cons "^ *\\([0-9]+\\)" 'font-lock-constant-face))))
342
343 (setq fortran-font-lock-keywords-3 332 (setq fortran-font-lock-keywords-3
344 (append 333 (append
345 ;;
346 ;; The list `fortran-font-lock-keywords-1'. 334 ;; The list `fortran-font-lock-keywords-1'.
347 fortran-font-lock-keywords-1 335 fortran-font-lock-keywords-1
348 ;;
349 ;; Fontify all type specifiers plus their declared items. 336 ;; Fontify all type specifiers plus their declared items.
350 (list 337 (list
351 (list (concat "\\<\\(" fortran-type-types "\\)\\>[ \t(/]*\\(*\\)?") 338 (list (concat "\\<\\(" fortran-type-types "\\)\\>[ \t(/]*\\(*\\)?")
352 ;; Fontify the type specifier. 339 ;; Fontify the type specifier.
353 '(1 font-lock-type-face) 340 '(1 font-lock-type-face)
363 ;; No need to clean up. 350 ;; No need to clean up.
364 nil 351 nil
365 ;; Fontify as a variable name, functions are 352 ;; Fontify as a variable name, functions are
366 ;; fontified elsewhere. 353 ;; fontified elsewhere.
367 (1 font-lock-variable-name-face nil t)))) 354 (1 font-lock-variable-name-face nil t))))
368 ;;
369 ;; Things extra to `fortran-font-lock-keywords-3' 355 ;; Things extra to `fortran-font-lock-keywords-3'
370 ;; (must be done first). 356 ;; (must be done first).
371 (list 357 (list
372 ;;
373 ;; Fontify goto-like `err=label'/`end=label' in read/write 358 ;; Fontify goto-like `err=label'/`end=label' in read/write
374 ;; statements. 359 ;; statements.
375 '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?" 360 '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?"
376 (1 font-lock-keyword-face) (4 font-lock-constant-face nil t)) 361 (1 font-lock-keyword-face) (4 font-lock-constant-face nil t))
377 ;;
378 ;; Highlight standard continuation character and in a 362 ;; Highlight standard continuation character and in a
379 ;; TAB-formatted line. 363 ;; TAB-formatted line.
380 '("^ \\([^ 0]\\)" 1 font-lock-string-face) 364 '("^ \\([^ 0]\\)" 1 font-lock-string-face)
381 '("^\t\\([1-9]\\)" 1 font-lock-string-face)) 365 '("^\t\\([1-9]\\)" 1 font-lock-string-face))
382 ;;
383 ;; The list `fortran-font-lock-keywords-2' less that for types 366 ;; The list `fortran-font-lock-keywords-2' less that for types
384 ;; (see above). 367 ;; (see above).
385 (cdr (nthcdr (length fortran-font-lock-keywords-1) 368 (cdr (nthcdr (length fortran-font-lock-keywords-1)
386 fortran-font-lock-keywords-2))))) 369 fortran-font-lock-keywords-2)))))
387 370
415 (if fortran-mode-map 398 (if fortran-mode-map
416 () 399 ()
417 (setq fortran-mode-map (make-sparse-keymap)) 400 (setq fortran-mode-map (make-sparse-keymap))
418 (define-key fortran-mode-map ";" 'fortran-abbrev-start) 401 (define-key fortran-mode-map ";" 'fortran-abbrev-start)
419 (define-key fortran-mode-map "\C-c;" 'fortran-comment-region) 402 (define-key fortran-mode-map "\C-c;" 'fortran-comment-region)
420 (define-key fortran-mode-map "\M-\C-a" 'beginning-of-fortran-subprogram) 403 (define-key fortran-mode-map "\M-\C-a" 'fortran-beginning-of-subprogram)
421 (define-key fortran-mode-map "\M-\C-e" 'end-of-fortran-subprogram) 404 (define-key fortran-mode-map "\M-\C-e" 'fortran-end-of-subprogram)
422 (define-key fortran-mode-map "\M-;" 'fortran-indent-comment) 405 (define-key fortran-mode-map "\M-;" 'fortran-indent-comment)
423 (define-key fortran-mode-map "\M-\C-h" 'mark-fortran-subprogram) 406 (define-key fortran-mode-map "\M-\C-h" 'fortran-mark-subprogram)
424 (define-key fortran-mode-map "\M-\n" 'fortran-split-line) 407 (define-key fortran-mode-map "\M-\n" 'fortran-split-line)
425 (define-key fortran-mode-map "\n" 'fortran-indent-new-line) 408 (define-key fortran-mode-map "\n" 'fortran-indent-new-line)
426 (define-key fortran-mode-map "\M-\C-q" 'fortran-indent-subprogram) 409 (define-key fortran-mode-map "\M-\C-q" 'fortran-indent-subprogram)
427 (define-key fortran-mode-map "\C-c\C-w" 'fortran-window-create-momentarily) 410 (define-key fortran-mode-map "\C-c\C-w" 'fortran-window-create-momentarily)
428 (define-key fortran-mode-map "\C-c\C-r" 'fortran-column-ruler) 411 (define-key fortran-mode-map "\C-c\C-r" 'fortran-column-ruler)
445 428
446 ;; Menu 429 ;; Menu
447 (unless (boundp 'fortran-mode-menu) 430 (unless (boundp 'fortran-mode-menu)
448 (easy-menu-define 431 (easy-menu-define
449 fortran-mode-menu fortran-mode-map "" 432 fortran-mode-menu fortran-mode-map ""
450 '("Fortran" 433 `("Fortran"
434 ["Manual" (info "(emacs)Fortran")]
435 ,(customize-menu-create 'fortran)
436 ["Set" Custom-set t]
437 ["Save" Custom-save t]
438 ["Reset to Current" Custom-reset-current t]
439 ["Reset to Saved" Custom-reset-saved t]
440 ["Reset to Standard Settings" Custom-reset-standard t]
441 "----"
451 ["Toggle Auto-fill" fortran-auto-fill-mode :style toggle 442 ["Toggle Auto-fill" fortran-auto-fill-mode :style toggle
452 :selected (eq auto-fill-function 'fortran-do-auto-fill)] 443 :selected (eq auto-fill-function 'fortran-do-auto-fill)]
453 ["Toggle abbrev-mode" abbrev-mode :style toggle :selected abbrev-mode] 444 ["Toggle abbrev-mode" abbrev-mode :style toggle :selected abbrev-mode]
454 "----" 445 "----"
455 ["Comment-out Region" fortran-comment-region mark-active] 446 ["Comment-out Region" fortran-comment-region mark-active]
457 (fortran-comment-region (region-beginning) (region-end) 1) 448 (fortran-comment-region (region-beginning) (region-end) 1)
458 mark-active] 449 mark-active]
459 ["Indent Region" indent-region mark-active] 450 ["Indent Region" indent-region mark-active]
460 ["Indent Subprogram" fortran-indent-subprogram t] 451 ["Indent Subprogram" fortran-indent-subprogram t]
461 "----" 452 "----"
462 ["Beginning of Subprogram" beginning-of-fortran-subprogram t] 453 ["Beginning of Subprogram" fortran-beginning-of-subprogram t]
463 ["End of Subprogram" end-of-fortran-subprogram t] 454 ["End of Subprogram" fortran-end-of-subprogram t]
464 ("Mark" 455 ("Mark"
465 ["Subprogram" mark-fortran-subprogram t] 456 ["Subprogram" fortran-mark-subprogram t]
466 ["IF Block" fortran-mark-if t] 457 ["IF Block" fortran-mark-if t]
467 ["DO Block" fortran-mark-do t]) 458 ["DO Block" fortran-mark-do t])
468 ["Narrow to Subprogram" fortran-narrow-to-subprogram t] 459 ["Narrow to Subprogram" fortran-narrow-to-subprogram t]
469 ["Widen" widen t] 460 ["Widen" widen t]
470 "----" 461 "----"
478 ["Break Line at Point" fortran-split-line t] 469 ["Break Line at Point" fortran-split-line t]
479 ["Join Line" fortran-join-line t] 470 ["Join Line" fortran-join-line t]
480 ["Fill Statement/Comment" fill-paragraph t] 471 ["Fill Statement/Comment" fill-paragraph t]
481 "----" 472 "----"
482 ["Add imenu menu" 473 ["Add imenu menu"
483 (progn (imenu-add-menubar-index) 474 imenu-add-menubar-index (not (and (boundp 'imenu--index-alist)
484 ;; Prod menu bar to update -- is this the right way? 475 imenu--index-alist))]))))
485 (menu-bar-mode 1))
486 (not (and (boundp 'imenu--index-alist)
487 imenu--index-alist))]))))
488 476
489 (defvar fortran-mode-abbrev-table nil) 477 (defvar fortran-mode-abbrev-table nil)
490 (if fortran-mode-abbrev-table 478 (if fortran-mode-abbrev-table
491 () 479 ()
492 (let ((ac abbrevs-changed)) 480 (let ((ac abbrevs-changed))
553 541
554 (eval-when-compile ; silence compiler 542 (eval-when-compile ; silence compiler
555 (defvar imenu-case-fold-search) 543 (defvar imenu-case-fold-search)
556 (defvar imenu-syntax-alist)) 544 (defvar imenu-syntax-alist))
557 545
546 (defcustom fortran-mode-hook nil
547 "Hook run by Fortran mode."
548 :type 'hook
549 :group 'fortran)
550
558 ;;;###autoload 551 ;;;###autoload
559 (defun fortran-mode () 552 (defun fortran-mode ()
560 "Major mode for editing Fortran code. 553 "Major mode for editing Fortran code.
561 \\[fortran-indent-line] indents the current Fortran line correctly. 554 \\[fortran-indent-line] indents the current Fortran line correctly.
562 DO statements must not share a common CONTINUE. 555 DO statements must not share a common CONTINUE.
618 region. (default \"c$$$\") 611 region. (default \"c$$$\")
619 `fortran-electric-line-number' 612 `fortran-electric-line-number'
620 Non-nil causes line number digits to be moved to the correct column 613 Non-nil causes line number digits to be moved to the correct column
621 as typed. (default t) 614 as typed. (default t)
622 `fortran-break-before-delimiters' 615 `fortran-break-before-delimiters'
623 Non-nil causes `fortran-fill' to break lines before delimiters. 616 Non-nil causes lines to be broken before delimiters.
624 (default t) 617 (default t)
625 618
626 Turning on Fortran mode calls the value of the variable `fortran-mode-hook' 619 Turning on Fortran mode calls the value of the variable `fortran-mode-hook'
627 with no args, if that value is non-nil." 620 with no args, if that value is non-nil."
628 (interactive) 621 (interactive)
634 (setq font-lock-defaults '((fortran-font-lock-keywords 627 (setq font-lock-defaults '((fortran-font-lock-keywords
635 fortran-font-lock-keywords-1 628 fortran-font-lock-keywords-1
636 fortran-font-lock-keywords-2 629 fortran-font-lock-keywords-2
637 fortran-font-lock-keywords-3) 630 fortran-font-lock-keywords-3)
638 nil t ((?/ . "$/") ("_$" . "w")) 631 nil t ((?/ . "$/") ("_$" . "w"))
639 beginning-of-fortran-subprogram)) 632 fortran-beginning-of-subprogram))
640 (set (make-local-variable 'font-lock-syntactic-keywords) 633 (set (make-local-variable 'font-lock-syntactic-keywords)
641 fortran-font-lock-syntactic-keywords) 634 fortran-font-lock-syntactic-keywords)
642 (make-local-variable 'fortran-break-before-delimiters) 635 (make-local-variable 'fortran-break-before-delimiters)
643 (setq fortran-break-before-delimiters t) 636 (setq fortran-break-before-delimiters t)
644 (make-local-variable 'indent-line-function) 637 (make-local-variable 'indent-line-function)
645 (setq indent-line-function 'fortran-indent-line) 638 (setq indent-line-function 'fortran-indent-line)
646 (make-local-variable 'comment-indent-function) 639 (make-local-variable 'comment-indent-function)
647 (setq comment-indent-function 'fortran-comment-hook) 640 (setq comment-indent-function 'fortran-comment-indent-function)
648 (make-local-variable 'comment-line-start-skip) 641 (make-local-variable 'fortran-comment-line-start-skip)
649 (setq comment-line-start-skip 642 (setq fortran-comment-line-start-skip
650 "^[Cc*]\\(\\([^ \t\n]\\)\\2\\2*\\)?[ \t]*\\|^#.*") 643 "^[Cc*]\\(\\([^ \t\n]\\)\\2\\2*\\)?[ \t]*\\|^#.*")
651 (make-local-variable 'comment-line-start) 644 (make-local-variable 'fortran-comment-line-start)
652 (setq comment-line-start "c") 645 (setq fortran-comment-line-start "c")
653 (make-local-variable 'comment-start-skip) 646 (make-local-variable 'comment-start-skip)
654 (setq comment-start-skip "![ \t]*") 647 (setq comment-start-skip "![ \t]*")
655 (make-local-variable 'comment-start) 648 (make-local-variable 'comment-start)
656 (setq comment-start nil) 649 (setq comment-start nil)
657 (make-local-variable 'require-final-newline) 650 (make-local-variable 'require-final-newline)
683 (let (fortran-blink-matching-if ; avoid blinking delay 676 (let (fortran-blink-matching-if ; avoid blinking delay
684 indent-region-function) 677 indent-region-function)
685 (indent-region start end nil)))) 678 (indent-region start end nil))))
686 (run-hooks 'fortran-mode-hook)) 679 (run-hooks 'fortran-mode-hook))
687 680
688 (defun fortran-comment-hook () 681 (defun fortran-comment-indent-function ()
689 (save-excursion 682 (save-excursion
690 (skip-chars-backward " \t") 683 (skip-chars-backward " \t")
691 (max (+ 1 (current-column)) 684 (max (+ 1 (current-column))
692 comment-column))) 685 comment-column)))
693 686
699 Otherwise, a separate-line comment is inserted, on this line 692 Otherwise, a separate-line comment is inserted, on this line
700 or on a new line inserted before this line if this line is not blank." 693 or on a new line inserted before this line if this line is not blank."
701 (interactive) 694 (interactive)
702 (beginning-of-line) 695 (beginning-of-line)
703 ;; Recognize existing comments of either kind. 696 ;; Recognize existing comments of either kind.
704 (cond ((looking-at comment-line-start-skip) 697 (cond ((looking-at fortran-comment-line-start-skip)
705 (fortran-indent-line)) 698 (fortran-indent-line))
706 ((fortran-find-comment-start-skip) ; catches any inline comment and 699 ((fortran-find-comment-start-skip) ; catches any inline comment and
707 ; leaves point after comment-start-skip 700 ; leaves point after comment-start-skip
708 (if comment-start-skip 701 (if comment-start-skip
709 (progn (goto-char (match-beginning 0)) 702 (progn (goto-char (match-beginning 0))
710 (if (not (= (current-column) (fortran-comment-hook))) 703 (if (not (= (current-column) (fortran-comment-indent-function)))
711 (progn (delete-horizontal-space) 704 (progn (delete-horizontal-space)
712 (indent-to (fortran-comment-hook))))) 705 (indent-to (fortran-comment-indent-function)))))
713 (end-of-line))) ; otherwise goto end of line or sth else? 706 (end-of-line))) ; otherwise goto end of line or sth else?
714 ;; No existing comment. 707 ;; No existing comment.
715 ;; If side-by-side comments are defined, insert one, 708 ;; If side-by-side comments are defined, insert one,
716 ;; unless line is now blank. 709 ;; unless line is now blank.
717 ((and comment-start (not (looking-at "^[ \t]*$"))) 710 ((and comment-start (not (looking-at "^[ \t]*$")))
718 (end-of-line) 711 (end-of-line)
719 (delete-horizontal-space) 712 (delete-horizontal-space)
720 (indent-to (fortran-comment-hook)) 713 (indent-to (fortran-comment-indent-function))
721 (insert comment-start)) 714 (insert comment-start))
722 ;; Else insert separate-line comment, making a new line if nec. 715 ;; Else insert separate-line comment, making a new line if nec.
723 (t 716 (t
724 (if (looking-at "^[ \t]*$") 717 (if (looking-at "^[ \t]*$")
725 (delete-horizontal-space) 718 (delete-horizontal-space)
726 (beginning-of-line) 719 (beginning-of-line)
727 (insert "\n") 720 (insert ?\n)
728 (forward-char -1)) 721 (forward-char -1))
729 (insert comment-line-start) 722 (insert fortran-comment-line-start)
730 (insert-char (if (stringp fortran-comment-indent-char) 723 (insert-char (if (stringp fortran-comment-indent-char)
731 (aref fortran-comment-indent-char 0) 724 (aref fortran-comment-indent-char 0)
732 fortran-comment-indent-char) 725 fortran-comment-indent-char)
733 (- (fortran-calculate-indent) (current-column)))))) 726 (- (fortran-calculate-indent) (current-column))))))
734 727
842 835
843 (defun fortran-split-line () 836 (defun fortran-split-line ()
844 "Break line at point and insert continuation marker and alignment." 837 "Break line at point and insert continuation marker and alignment."
845 (interactive) 838 (interactive)
846 (delete-horizontal-space) 839 (delete-horizontal-space)
847 (if (save-excursion (beginning-of-line) (looking-at comment-line-start-skip)) 840 (if (save-excursion
848 (insert "\n" comment-line-start " ") 841 (beginning-of-line)
842 (looking-at fortran-comment-line-start-skip))
843 (insert ?\n fortran-comment-line-start ? )
849 (if indent-tabs-mode 844 (if indent-tabs-mode
850 (insert "\n\t" (fortran-numerical-continuation-char)) 845 (insert ?\n ?\t (fortran-numerical-continuation-char))
851 (insert "\n " fortran-continuation-string))) ; Space after \n important 846 (insert "\n " fortran-continuation-string))) ; Space after \n important
852 (fortran-indent-line)) ; when the cont string is C, c or *. 847 (fortran-indent-line)) ; when the cont string is C, c or *.
853 848
854 (defun fortran-remove-continuation () 849 (defun fortran-remove-continuation ()
855 (if (looking-at "\\( [^ 0\n]\\|\t[1-9]\\|&\\)") 850 (if (looking-at "\\( [^ 0\n]\\|\t[1-9]\\|&\\)")
882 (forward-line -1) 877 (forward-line -1)
883 (if (looking-at "\t[1-9]") 878 (if (looking-at "\t[1-9]")
884 (+ ?1 (% (- (char-after (+ (point) 1)) ?0) 9)) 879 (+ ?1 (% (- (char-after (+ (point) 1)) ?0) 9))
885 ?1))) 880 ?1)))
886 881
887 (defun delete-horizontal-regexp (chars)
888 "Delete all characters in CHARS around point.
889 CHARS is like the inside of a [...] in a regular expression
890 except that ] is never special and \ quotes ^, - or \."
891 (interactive "*s")
892 (skip-chars-backward chars)
893 (delete-region (point) (progn (skip-chars-forward chars) (point))))
894
895 (put 'fortran-electric-line-number 'delete-selection t) 882 (put 'fortran-electric-line-number 'delete-selection t)
896 (defun fortran-electric-line-number (arg) 883 (defun fortran-electric-line-number (arg)
897 "Self insert, but if part of a Fortran line number indent it automatically. 884 "Self insert, but if part of a Fortran line number indent it automatically.
898 Auto-indent does not happen if a numeric ARG is used." 885 Auto-indent does not happen if a numeric ARG is used."
899 (interactive "P") 886 (interactive "P")
902 (self-insert-command (prefix-numeric-value arg)) 889 (self-insert-command (prefix-numeric-value arg))
903 (self-insert-command 1)) 890 (self-insert-command 1))
904 (if (or (and (= 5 (current-column)) 891 (if (or (and (= 5 (current-column))
905 (save-excursion 892 (save-excursion
906 (beginning-of-line) 893 (beginning-of-line)
907 (looking-at " ")));In col 5 with only spaces to left. 894 (looking-at " "))) ;In col 5 with only spaces to left.
908 (and (= (if indent-tabs-mode 895 (and (= (if indent-tabs-mode
909 fortran-minimum-statement-indent-tab 896 fortran-minimum-statement-indent-tab
910 fortran-minimum-statement-indent-fixed) (current-column)) 897 fortran-minimum-statement-indent-fixed) (current-column))
911 (save-excursion 898 (eq ?\t (char-after (line-beginning-position))) ;In col 8
912 (beginning-of-line) 899 ; with a single tab to the left.
913 (looking-at "\t"));In col 8 with a single tab to the left.
914 (not (or (eq last-command 'fortran-indent-line) 900 (not (or (eq last-command 'fortran-indent-line)
915 (eq last-command 901 (eq last-command
916 'fortran-indent-new-line)))) 902 'fortran-indent-new-line))))
917 (save-excursion 903 (save-excursion
918 (re-search-backward "[^ \t0-9]" 904 (re-search-backward "[^ \t0-9]"
919 (save-excursion 905 (line-beginning-position)
920 (beginning-of-line)
921 (point))
922 t)) ;not a line number 906 t)) ;not a line number
923 (looking-at "[0-9]")) ;within a line number 907 (looking-at "[0-9]")) ;within a line number
924 (self-insert-command (prefix-numeric-value arg)) 908 (self-insert-command (prefix-numeric-value arg))
925 (skip-chars-backward " \t") 909 (skip-chars-backward " \t")
926 (insert last-command-char) 910 (insert last-command-char)
944 (min (line-end-position) 928 (min (line-end-position)
945 (+ 72 (line-beginning-position))))))) 929 (+ 72 (line-beginning-position)))))))
946 930
947 ;; Note that you can't just check backwards for `subroutine' &c in 931 ;; Note that you can't just check backwards for `subroutine' &c in
948 ;; case of un-marked main programs not at the start of the file. 932 ;; case of un-marked main programs not at the start of the file.
949 (defun beginning-of-fortran-subprogram () 933 (defun fortran-beginning-of-subprogram ()
950 "Moves point to the beginning of the current Fortran subprogram." 934 "Moves point to the beginning of the current Fortran subprogram."
951 (interactive) 935 (interactive)
952 (save-match-data 936 (save-match-data
953 (let ((case-fold-search t)) 937 (let ((case-fold-search t))
954 (beginning-of-line -1) 938 (beginning-of-line -1)
956 (while (re-search-backward fortran-end-prog-re nil 'move) 940 (while (re-search-backward fortran-end-prog-re nil 'move)
957 (if (fortran-check-end-prog-re) 941 (if (fortran-check-end-prog-re)
958 (throw 'ok t)))) 942 (throw 'ok t))))
959 (forward-line))))) 943 (forward-line)))))
960 944
961 (defun end-of-fortran-subprogram () 945 (defun fortran-end-of-subprogram ()
962 "Moves point to the end of the current Fortran subprogram." 946 "Moves point to the end of the current Fortran subprogram."
963 (interactive) 947 (interactive)
964 (save-match-data 948 (save-match-data
965 (let ((case-fold-search t)) 949 (let ((case-fold-search t))
966 (if (save-excursion ; on END 950 (if (save-excursion ; on END
974 (if (fortran-check-end-prog-re) 958 (if (fortran-check-end-prog-re)
975 (throw 'ok t)))) 959 (throw 'ok t))))
976 (goto-char (match-beginning 0)) 960 (goto-char (match-beginning 0))
977 (forward-line))))) 961 (forward-line)))))
978 962
979 (defun mark-fortran-subprogram () 963 (defun fortran-mark-subprogram ()
980 "Put mark at end of Fortran subprogram, point at beginning. 964 "Put mark at end of Fortran subprogram, point at beginning.
981 The marks are pushed." 965 The marks are pushed."
982 (interactive) 966 (interactive)
983 (end-of-fortran-subprogram) 967 (fortran-end-of-subprogram)
984 (push-mark (point) nil t) 968 (push-mark (point) nil t)
985 (beginning-of-fortran-subprogram)) 969 (fortran-beginning-of-subprogram))
986 970
987 (defun fortran-previous-statement () 971 (defun fortran-previous-statement ()
988 "Moves point to beginning of the previous Fortran statement. 972 "Moves point to beginning of the previous Fortran statement.
989 Returns `first-statement' if that statement is the first 973 Returns `first-statement' if that statement is the first
990 non-comment Fortran statement in the file, and nil otherwise." 974 non-comment Fortran statement in the file, and nil otherwise."
991 (interactive) 975 (interactive)
992 (let (not-first-statement continue-test) 976 (let (not-first-statement continue-test)
993 (beginning-of-line) 977 (beginning-of-line)
994 (setq continue-test 978 (setq continue-test
995 (and 979 (and
996 (not (looking-at comment-line-start-skip)) 980 (not (looking-at fortran-comment-line-start-skip))
997 (or (looking-at 981 (or (looking-at
998 (concat "[ \t]*" (regexp-quote fortran-continuation-string))) 982 (concat "[ \t]*" (regexp-quote fortran-continuation-string)))
999 (or (looking-at " [^ 0\n]") 983 (looking-at " [^ 0\n]\\|\t[1-9]"))))
1000 (looking-at "\t[1-9]")))))
1001 (while (and (setq not-first-statement (= (forward-line -1) 0)) 984 (while (and (setq not-first-statement (= (forward-line -1) 0))
1002 (or (looking-at comment-line-start-skip) 985 (or (looking-at fortran-comment-line-start-skip)
1003 (looking-at "[ \t]*$") 986 (looking-at "[ \t]*$\\| [^ 0\n]\\|\t[1-9]")
1004 (looking-at " [^ 0\n]")
1005 (looking-at "\t[1-9]")
1006 (looking-at (concat "[ \t]*" comment-start-skip))))) 987 (looking-at (concat "[ \t]*" comment-start-skip)))))
1007 (cond ((and continue-test 988 (cond ((and continue-test
1008 (not not-first-statement)) 989 (not not-first-statement))
1009 (message "Incomplete continuation statement.")) 990 (message "Incomplete continuation statement."))
1010 (continue-test 991 (continue-test
1020 (let (not-last-statement) 1001 (let (not-last-statement)
1021 (beginning-of-line) 1002 (beginning-of-line)
1022 (while (and (setq not-last-statement 1003 (while (and (setq not-last-statement
1023 (and (= (forward-line 1) 0) 1004 (and (= (forward-line 1) 0)
1024 (not (eobp)))) 1005 (not (eobp))))
1025 (or (looking-at comment-line-start-skip) 1006 (or (looking-at fortran-comment-line-start-skip)
1026 (looking-at "[ \t]*$") 1007 (looking-at "[ \t]*$\\| [^ 0\n]\\|\t[1-9]")
1027 (looking-at " [^ 0\n]")
1028 (looking-at "\t[1-9]")
1029 (looking-at (concat "[ \t]*" comment-start-skip))))) 1008 (looking-at (concat "[ \t]*" comment-start-skip)))))
1030 (if (not not-last-statement) 1009 (if (not not-last-statement)
1031 'last-statement))) 1010 'last-statement)))
1032 1011
1033 (defun fortran-narrow-to-subprogram () 1012 (defun fortran-narrow-to-subprogram ()
1034 "Make text outside the current subprogram invisible. 1013 "Make text outside the current subprogram invisible.
1035 The subprogram visible is the one that contains or follows point." 1014 The subprogram visible is the one that contains or follows point."
1036 (interactive) 1015 (interactive)
1037 (save-excursion 1016 (save-excursion
1038 (mark-fortran-subprogram) 1017 (fortran-mark-subprogram)
1039 (narrow-to-region (point) (mark)))) 1018 (narrow-to-region (point) (mark))))
1040 1019
1041 (defmacro fortran-with-subprogram-narrowing (&rest forms) 1020 (defmacro fortran-with-subprogram-narrowing (&rest forms)
1042 "Execute FORMS with buffer temporarily narrowed to current subprogram. 1021 "Execute FORMS with buffer temporarily narrowed to current subprogram.
1043 Doesn't push a mark." 1022 Doesn't push a mark."
1044 `(save-restriction 1023 `(save-restriction
1045 (save-excursion 1024 (save-excursion
1046 (narrow-to-region (progn 1025 (narrow-to-region (progn
1047 (beginning-of-fortran-subprogram) 1026 (fortran-beginning-of-subprogram)
1048 (point)) 1027 (point))
1049 (progn 1028 (progn
1050 (end-of-fortran-subprogram) 1029 (fortran-end-of-subprogram)
1051 (point)))) 1030 (point))))
1052 ,@forms)) 1031 ,@forms))
1053 1032
1054 (defun fortran-blink-matching-if () 1033 (defun fortran-blink-match (regex keyword find-begin)
1055 "From an ENDIF statement, blink the matching IF statement." 1034 "From a line matching REGEX, blink matching KEYWORD statement line.
1035 Use function FIND-BEGIN to match it."
1056 (let ((top-of-window (window-start)) 1036 (let ((top-of-window (window-start))
1057 (endif-point (point)) 1037 (end-point (point))
1058 (case-fold-search t) 1038 (case-fold-search t)
1059 matching-if 1039 matching
1060 message) 1040 message)
1061 (if (save-excursion (beginning-of-line) 1041 (if (save-excursion
1062 (skip-chars-forward " \t0-9") 1042 (beginning-of-line)
1063 (looking-at "e\\(nd[ \t]*if\\|lse\\([ \t]*if\\)?\\)\\b")) 1043 (skip-chars-forward " \t0-9")
1044 (looking-at regex))
1064 (progn 1045 (progn
1065 (if (not (setq matching-if (fortran-beginning-if))) 1046 (if (not (setq matching (funcall find-begin)))
1066 (setq message "No matching if.") 1047 (setq message (concat "No matching " keyword "."))
1067 (if (< matching-if top-of-window) 1048 (if (< matching top-of-window)
1068 (save-excursion 1049 (save-excursion
1069 (goto-char matching-if) 1050 (goto-char matching)
1070 (beginning-of-line) 1051 (beginning-of-line)
1071 (setq message 1052 (setq message
1072 (concat "Matches " 1053 (concat "Matches "
1073 (buffer-substring 1054 (buffer-substring (point)
1074 (point) (progn (end-of-line) (point)))))))) 1055 (line-end-position)))))))
1075 (if message 1056 (if message
1076 (message "%s" message) 1057 (message "%s" message)
1077 (goto-char matching-if) 1058 (goto-char matching)
1078 (sit-for 1) 1059 (sit-for 1)
1079 (goto-char endif-point)))))) 1060 (goto-char end-point))))))
1061
1062 (defun fortran-blink-matching-if ()
1063 "From an ENDIF or ELSE statement, blink the matching IF statement."
1064 (fortran-blink-match "e\\(nd[ \t]*if\\|lse\\([ \t]*if\\)?\\)\\b"
1065 "if" #'fortran-beginning-if))
1080 1066
1081 (defun fortran-blink-matching-do () 1067 (defun fortran-blink-matching-do ()
1082 "From an ENDDO statement, blink the matching DO or DO WHILE statement." 1068 "From an ENDDO statement, blink the matching DO or DO WHILE statement."
1083 ;; This is basically copied from fortran-blink-matching-if. 1069 (fortran-blink-match "end[ \t]*do\\b" "do" #'fortran-beginning-do))
1084 (let ((top-of-window (window-start))
1085 (enddo-point (point))
1086 (case-fold-search t)
1087 matching-do
1088 message)
1089 (if (save-excursion (beginning-of-line)
1090 (skip-chars-forward " \t0-9")
1091 (looking-at "end[ \t]*do\\b"))
1092 (progn
1093 (if (not (setq matching-do (fortran-beginning-do)))
1094 (setq message "No matching do.")
1095 (if (< matching-do top-of-window)
1096 (save-excursion
1097 (goto-char matching-do)
1098 (beginning-of-line)
1099 (setq message
1100 (concat "Matches "
1101 (buffer-substring
1102 (point) (progn (end-of-line) (point))))))))
1103 (if message
1104 (message "%s" message)
1105 (goto-char matching-do)
1106 (sit-for 1)
1107 (goto-char enddo-point))))))
1108 1070
1109 (defun fortran-mark-do () 1071 (defun fortran-mark-do ()
1110 "Put mark at end of Fortran DO [WHILE]-ENDDO construct, point at beginning. 1072 "Put mark at end of Fortran DO [WHILE]-ENDDO construct, point at beginning.
1111 The marks are pushed." 1073 The marks are pushed."
1112 (interactive) 1074 (interactive)
1113 (let (enddo-point do-point) 1075 (let (enddo-point do-point)
1114 (if (setq enddo-point (fortran-end-do)) 1076 (if (setq enddo-point (fortran-end-do))
1115 (if (not (setq do-point (fortran-beginning-do))) 1077 (if (not (setq do-point (fortran-beginning-do)))
1116 (message "No matching do.") 1078 (message "No matching do.")
1117 ;; Set mark, move point.
1118 (goto-char enddo-point) 1079 (goto-char enddo-point)
1119 (push-mark) 1080 (push-mark)
1120 (goto-char do-point))))) 1081 (goto-char do-point)))))
1121 1082
1122 (defun fortran-end-do () 1083 (defun fortran-end-do ()
1129 ;; Sitting on one. 1090 ;; Sitting on one.
1130 (match-beginning 0) 1091 (match-beginning 0)
1131 ;; Search for one. 1092 ;; Search for one.
1132 (save-excursion 1093 (save-excursion
1133 (let ((count 1)) 1094 (let ((count 1))
1134 (while (and (not (= count 0)) 1095 (while (and (not (= count 0))
1135 (not (eq (fortran-next-statement) 'last-statement)) 1096 (not (eq (fortran-next-statement) 'last-statement))
1136 ;; Keep local to subprogram 1097 ;; Keep local to subprogram
1137 (not (and (looking-at fortran-end-prog-re) 1098 (not (and (looking-at fortran-end-prog-re)
1138 (fortran-check-end-prog-re)))) 1099 (fortran-check-end-prog-re))))
1139
1140 (skip-chars-forward " \t0-9") 1100 (skip-chars-forward " \t0-9")
1141 (cond ((looking-at "end[ \t]*do\\b") 1101 (cond ((looking-at "end[ \t]*do\\b")
1142 (setq count (1- count))) 1102 (setq count (1- count)))
1143 ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]") 1103 ((looking-at
1144 (setq count (+ count 1))))) 1104 "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]")
1145 (and (= count 0) 1105 (setq count (+ count 1)))))
1106 (and (= count 0)
1146 ;; All pairs accounted for. 1107 ;; All pairs accounted for.
1147 (point))))))) 1108 (point)))))))
1148 1109
1149 (defun fortran-beginning-do () 1110 (defun fortran-beginning-do ()
1150 "Search backwards for first unmatched DO [WHILE]. 1111 "Search backwards for first unmatched DO [WHILE].
1151 Return point or nil." 1112 Return point or nil."
1152 (let ((case-fold-search t)) 1113 (let ((case-fold-search t))
1153 (if (save-excursion (beginning-of-line) 1114 (if (save-excursion
1154 (skip-chars-forward " \t0-9") 1115 (beginning-of-line)
1155 (looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+")) 1116 (skip-chars-forward " \t0-9")
1117 (looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+"))
1156 ;; Sitting on one. 1118 ;; Sitting on one.
1157 (match-beginning 0) 1119 (match-beginning 0)
1158 ;; Search for one. 1120 ;; Search for one.
1159 (save-excursion 1121 (save-excursion
1160 (let ((count 1)) 1122 (let ((count 1))
1161 (while (and (not (= count 0)) 1123 (while (and (not (= count 0))
1162 (not (eq (fortran-previous-statement) 'first-statement)) 1124 (not (eq (fortran-previous-statement) 'first-statement))
1163 ;; Keep local to subprogram 1125 ;; Keep local to subprogram
1164 (not (and (looking-at fortran-end-prog-re) 1126 (not (and (looking-at fortran-end-prog-re)
1165 (fortran-check-end-prog-re)))) 1127 (fortran-check-end-prog-re))))
1166
1167 (skip-chars-forward " \t0-9") 1128 (skip-chars-forward " \t0-9")
1168 (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]") 1129 (cond ((looking-at
1130 "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]")
1169 (setq count (1- count))) 1131 (setq count (1- count)))
1170 ((looking-at "end[ \t]*do\\b") 1132 ((looking-at "end[ \t]*do\\b")
1171 (setq count (1+ count))))) 1133 (setq count (1+ count)))))
1172 1134 (and (= count 0)
1173 (and (= count 0)
1174 ;; All pairs accounted for. 1135 ;; All pairs accounted for.
1175 (point))))))) 1136 (point)))))))
1176 1137
1177 (defun fortran-mark-if () 1138 (defun fortran-mark-if ()
1178 "Put mark at end of Fortran IF-ENDIF construct, point at beginning. 1139 "Put mark at end of Fortran IF-ENDIF construct, point at beginning.
1200 (match-beginning 0) 1161 (match-beginning 0)
1201 ;; Search for one. The point has been already been moved to first 1162 ;; Search for one. The point has been already been moved to first
1202 ;; letter on line but this should not cause troubles. 1163 ;; letter on line but this should not cause troubles.
1203 (save-excursion 1164 (save-excursion
1204 (let ((count 1)) 1165 (let ((count 1))
1205 (while (and (not (= count 0)) 1166 (while (and (not (= count 0))
1206 (not (eq (fortran-next-statement) 'last-statement)) 1167 (not (eq (fortran-next-statement) 'last-statement))
1207 ;; Keep local to subprogram. 1168 ;; Keep local to subprogram.
1208 (not (and (looking-at fortran-end-prog-re) 1169 (not (and (looking-at fortran-end-prog-re)
1209 (fortran-check-end-prog-re)))) 1170 (fortran-check-end-prog-re))))
1210
1211 (skip-chars-forward " \t0-9") 1171 (skip-chars-forward " \t0-9")
1212 (cond ((looking-at "end[ \t]*if\\b") 1172 (cond ((looking-at "end[ \t]*if\\b")
1213 (setq count (- count 1))) 1173 (setq count (- count 1)))
1214
1215 ((looking-at fortran-if-start-re) 1174 ((looking-at fortran-if-start-re)
1216 (save-excursion 1175 (save-excursion
1217 (if (or 1176 (if (or
1218 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") 1177 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
1219 (let (then-test) ; Multi-line if-then. 1178 (let (then-test) ; Multi-line if-then.
1220 (while 1179 (while
1221 (and (= (forward-line 1) 0) 1180 (and (= (forward-line 1) 0)
1222 ;; Search forward for then. 1181 ;; Search forward for then.
1223 (or (looking-at " [^ 0\n]") 1182 (looking-at " [^ 0\n]\\|\t[1-9]")
1224 (looking-at "\t[1-9]"))
1225 (not 1183 (not
1226 (setq then-test 1184 (setq then-test
1227 (looking-at 1185 (looking-at
1228 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) 1186 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
1229 then-test)) 1187 then-test))
1230 (setq count (+ count 1))))))) 1188 (setq count (+ count 1)))))))
1231 1189 (and (= count 0)
1232 (and (= count 0)
1233 ;; All pairs accounted for. 1190 ;; All pairs accounted for.
1234 (point))))))) 1191 (point)))))))
1235 1192
1236 (defun fortran-beginning-if () 1193 (defun fortran-beginning-if ()
1237 "Search backwards for first unmatched IF-THEN. 1194 "Search backwards for first unmatched IF-THEN.
1238 Return point or nil." 1195 Return point or nil."
1239 (let ((case-fold-search t)) 1196 (let ((case-fold-search t))
1240 (if (save-excursion 1197 (if (save-excursion
1241 ;; May be sitting on multi-line if-then statement, first move to 1198 ;; May be sitting on multi-line if-then statement, first
1242 ;; beginning of current statement. Note: `fortran-previous-statement' 1199 ;; move to beginning of current statement. Note:
1243 ;; moves to previous statement *unless* current statement is first 1200 ;; `fortran-previous-statement' moves to previous statement
1244 ;; one. Only move forward if not first-statement. 1201 ;; *unless* current statement is first one. Only move
1202 ;; forward if not first-statement.
1245 (if (not (eq (fortran-previous-statement) 'first-statement)) 1203 (if (not (eq (fortran-previous-statement) 'first-statement))
1246 (fortran-next-statement)) 1204 (fortran-next-statement))
1247 (skip-chars-forward " \t0-9") 1205 (skip-chars-forward " \t0-9")
1248 (and 1206 (and
1249 (looking-at fortran-if-start-re) 1207 (looking-at fortran-if-start-re)
1252 ;; Multi-line if-then. 1210 ;; Multi-line if-then.
1253 (let (then-test) 1211 (let (then-test)
1254 (while 1212 (while
1255 (and (= (forward-line 1) 0) 1213 (and (= (forward-line 1) 0)
1256 ;; Search forward for then. 1214 ;; Search forward for then.
1257 (or (looking-at " [^ 0\n]") 1215 (looking-at " [^ 0\n]\\|\t[1-9]")
1258 (looking-at "\t[1-9]"))
1259 (not 1216 (not
1260 (setq then-test 1217 (setq then-test
1261 (looking-at 1218 (looking-at
1262 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) 1219 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
1263 then-test))))) 1220 then-test)))))
1264 ;; Sitting on one. 1221 ;; Sitting on one.
1265 (match-beginning 0) 1222 (match-beginning 0)
1266 ;; Search for one. 1223 ;; Search for one.
1267 (save-excursion 1224 (save-excursion
1268 (let ((count 1)) 1225 (let ((count 1))
1269 (while (and (not (= count 0)) 1226 (while (and (not (= count 0))
1270 (not (eq (fortran-previous-statement) 'first-statement)) 1227 (not (eq (fortran-previous-statement) 'first-statement))
1271 ;; Keep local to subprogram. 1228 ;; Keep local to subprogram.
1272 (not (and (looking-at fortran-end-prog-re) 1229 (not (and (looking-at fortran-end-prog-re)
1273 (fortran-check-end-prog-re)))) 1230 (fortran-check-end-prog-re))))
1274
1275 (skip-chars-forward " \t0-9") 1231 (skip-chars-forward " \t0-9")
1276 (cond ((looking-at fortran-if-start-re) 1232 (cond ((looking-at fortran-if-start-re)
1277 (save-excursion 1233 (save-excursion
1278 (if (or 1234 (if (or
1279 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") 1235 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
1280 (let (then-test) ; Multi-line if-then. 1236 (let (then-test) ; Multi-line if-then.
1281 (while 1237 (while
1282 (and (= (forward-line 1) 0) 1238 (and (= (forward-line 1) 0)
1283 ;; Search forward for then. 1239 ;; Search forward for then.
1284 (or (looking-at " [^ 0\n]") 1240 (looking-at " [^ 0\n]\\|\t[1-9]")
1285 (looking-at "\t[1-9]"))
1286 (not 1241 (not
1287 (setq then-test 1242 (setq then-test
1288 (looking-at 1243 (looking-at
1289 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) 1244 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
1290 then-test)) 1245 then-test))
1291 (setq count (- count 1))))) 1246 (setq count (- count 1)))))
1292 ((looking-at "end[ \t]*if\\b") 1247 ((looking-at "end[ \t]*if\\b")
1293 (setq count (+ count 1))))) 1248 (setq count (+ count 1)))))
1294 1249 (and (= count 0)
1295 (and (= count 0)
1296 ;; All pairs accounted for. 1250 ;; All pairs accounted for.
1297 (point))))))) 1251 (point)))))))
1298 1252
1299 (defun fortran-indent-line () 1253 (defun fortran-indent-line ()
1300 "Indent current Fortran line based on its contents and on previous lines." 1254 "Indent current Fortran line based on its contents and on previous lines."
1305 (if (or (not (= cfi (fortran-current-line-indentation))) 1259 (if (or (not (= cfi (fortran-current-line-indentation)))
1306 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t) 1260 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t)
1307 (not (fortran-line-number-indented-correctly-p)))) 1261 (not (fortran-line-number-indented-correctly-p))))
1308 (fortran-indent-to-column cfi) 1262 (fortran-indent-to-column cfi)
1309 (beginning-of-line) 1263 (beginning-of-line)
1310 (if (and (not (looking-at comment-line-start-skip)) 1264 (if (and (not (looking-at fortran-comment-line-start-skip))
1311 (fortran-find-comment-start-skip)) 1265 (fortran-find-comment-start-skip))
1312 (fortran-indent-comment)))) 1266 (fortran-indent-comment))))
1313 ;; Never leave point in left margin. 1267 ;; Never leave point in left margin.
1314 (if (< (current-column) cfi) 1268 (if (< (current-column) cfi)
1315 (move-to-column cfi)) 1269 (move-to-column cfi))
1316 (if (and auto-fill-function 1270 (if (and auto-fill-function
1317 (> (save-excursion (end-of-line) (current-column)) fill-column)) 1271 (> (save-excursion (end-of-line) (current-column))
1272 fill-column))
1318 (save-excursion 1273 (save-excursion
1319 (end-of-line) 1274 (end-of-line)
1320 (fortran-fill))) 1275 (fortran-fill)))
1321 (if fortran-blink-matching-if 1276 (if fortran-blink-matching-if
1322 (progn 1277 (progn
1329 1284
1330 (defun fortran-indent-subprogram () 1285 (defun fortran-indent-subprogram ()
1331 "Properly indent the Fortran subprogram which contains point." 1286 "Properly indent the Fortran subprogram which contains point."
1332 (interactive) 1287 (interactive)
1333 (save-excursion 1288 (save-excursion
1334 (mark-fortran-subprogram) 1289 (fortran-mark-subprogram)
1335 (message "Indenting subprogram...") 1290 (message "Indenting subprogram...")
1336 (indent-region (point) (mark) nil)) 1291 (indent-region (point) (mark) nil))
1337 (message "Indenting subprogram...done.")) 1292 (message "Indenting subprogram...done."))
1338 1293
1339 (defun fortran-calculate-indent () 1294 (defun fortran-calculate-indent ()
1355 (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(") 1310 (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(")
1356 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]") 1311 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]")
1357 (let (then-test) ;multi-line if-then 1312 (let (then-test) ;multi-line if-then
1358 (while (and (= (forward-line 1) 0) 1313 (while (and (= (forward-line 1) 0)
1359 ;;search forward for then 1314 ;;search forward for then
1360 (or (looking-at " [^ 0\n]") 1315 (looking-at " [^ 0\n]\\|\t[1-9]")
1361 (looking-at "\t[1-9]")) 1316 (not (setq then-test
1362 (not (setq then-test (looking-at 1317 (looking-at
1363 ".*then\\b[ \t]\ 1318 ".*then\\b[ \t]\
1364 *[^ \t_$(=a-z0-9]"))))) 1319 *[^ \t_$(=a-z0-9]")))))
1365 then-test)) 1320 then-test))
1366 (setq icol (+ icol fortran-if-indent)))) 1321 (setq icol (+ icol fortran-if-indent))))
1367 ((looking-at "else\\(if\\)?\\b") 1322 ((looking-at "else\\(if\\)?\\b")
1368 (setq icol (+ icol fortran-if-indent))) 1323 (setq icol (+ icol fortran-if-indent)))
1377 ((looking-at "where[ \t]*(.*)[ \t]*\n") 1332 ((looking-at "where[ \t]*(.*)[ \t]*\n")
1378 (setq icol (+ icol fortran-if-indent))) 1333 (setq icol (+ icol fortran-if-indent)))
1379 ((looking-at "do\\b") 1334 ((looking-at "do\\b")
1380 (setq icol (+ icol fortran-do-indent))) 1335 (setq icol (+ icol fortran-do-indent)))
1381 ((looking-at 1336 ((looking-at
1382 "\\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]") 1337 "\\(structure\\|union\\|map\\|interface\\)\
1338 \\b[ \t]*[^ \t=(a-z]")
1383 (setq icol (+ icol fortran-structure-indent))) 1339 (setq icol (+ icol fortran-structure-indent)))
1384 ((and (looking-at fortran-end-prog-re1) 1340 ((and (looking-at fortran-end-prog-re1)
1385 (fortran-check-end-prog-re)) 1341 (fortran-check-end-prog-re))
1386 ;; Previous END resets indent to minimum 1342 ;; Previous END resets indent to minimum
1387 (setq icol fortran-minimum-statement-indent)))))) 1343 (setq icol fortran-minimum-statement-indent))))))
1388 (save-excursion 1344 (save-excursion
1389 (beginning-of-line) 1345 (beginning-of-line)
1390 (cond ((looking-at "[ \t]*$")) 1346 (cond ((looking-at "[ \t]*$"))
1391 ((looking-at comment-line-start-skip) 1347 ((looking-at fortran-comment-line-start-skip)
1392 (cond ((eq fortran-comment-indent-style 'relative) 1348 (cond ((eq fortran-comment-indent-style 'relative)
1393 (setq icol (+ icol fortran-comment-line-extra-indent))) 1349 (setq icol (+ icol fortran-comment-line-extra-indent)))
1394 ((eq fortran-comment-indent-style 'fixed) 1350 ((eq fortran-comment-indent-style 'fixed)
1395 (setq icol (+ fortran-minimum-statement-indent 1351 (setq icol (+ fortran-minimum-statement-indent
1396 fortran-comment-line-extra-indent)))) 1352 fortran-comment-line-extra-indent))))
1397 (setq fortran-minimum-statement-indent 0)) 1353 (setq fortran-minimum-statement-indent 0))
1398 ((or (looking-at (concat "[ \t]*" 1354 ((or (looking-at (concat "[ \t]*"
1399 (regexp-quote 1355 (regexp-quote
1400 fortran-continuation-string))) 1356 fortran-continuation-string)))
1401 (looking-at " [^ 0\n]") 1357 (looking-at " [^ 0\n]\\|\t[1-9]"))
1402 (looking-at "\t[1-9]"))
1403 (setq icol (+ icol fortran-continuation-indent))) 1358 (setq icol (+ icol fortran-continuation-indent)))
1404 ((looking-at "[ \t]*#") ; Check for cpp directive. 1359 ((looking-at "[ \t]*#") ; Check for cpp directive.
1405 (setq fortran-minimum-statement-indent 0 icol 0)) 1360 (setq fortran-minimum-statement-indent 0 icol 0))
1406 (first-statement) 1361 (first-statement)
1407 ((and fortran-check-all-num-for-matching-do 1362 ((and fortran-check-all-num-for-matching-do
1439 aside from the line number and/or column 5/8 line-continuation character. 1394 aside from the line number and/or column 5/8 line-continuation character.
1440 For comment lines, returns indentation of the first 1395 For comment lines, returns indentation of the first
1441 non-indentation text within the comment." 1396 non-indentation text within the comment."
1442 (save-excursion 1397 (save-excursion
1443 (beginning-of-line) 1398 (beginning-of-line)
1444 (cond ((looking-at comment-line-start-skip) 1399 (cond ((looking-at fortran-comment-line-start-skip)
1445 (goto-char (match-end 0)) 1400 (goto-char (match-end 0))
1446 (skip-chars-forward 1401 (skip-chars-forward
1447 (if (stringp fortran-comment-indent-char) 1402 (if (stringp fortran-comment-indent-char)
1448 fortran-comment-indent-char 1403 fortran-comment-indent-char
1449 (char-to-string fortran-comment-indent-char)))) 1404 (char-to-string fortran-comment-indent-char))))
1450 ((or (looking-at " [^ 0\n]") 1405 ((or (looking-at " [^ 0\n]\\|\t[1-9]"))
1451 (looking-at "\t[1-9]"))
1452 (goto-char (match-end 0))) 1406 (goto-char (match-end 0)))
1453 (t 1407 (t
1454 ;; Move past line number. 1408 ;; Move past line number.
1455 (skip-chars-forward "[ \t0-9]");From Uli 1409 (skip-chars-forward "[ \t0-9]")))
1456 ))
1457 ;; Move past whitespace. 1410 ;; Move past whitespace.
1458 (skip-chars-forward " \t") 1411 (skip-chars-forward " \t")
1459 (current-column))) 1412 (current-column)))
1460 1413
1461 (defun fortran-indent-to-column (col) 1414 (defun fortran-indent-to-column (col)
1467 3) A non-continuation line which has a number as the first 1420 3) A non-continuation line which has a number as the first
1468 non-whitespace character is a numbered line. 1421 non-whitespace character is a numbered line.
1469 4) A TAB followed by a digit indicates a continuation line." 1422 4) A TAB followed by a digit indicates a continuation line."
1470 (save-excursion 1423 (save-excursion
1471 (beginning-of-line) 1424 (beginning-of-line)
1472 (if (looking-at comment-line-start-skip) 1425 (if (looking-at fortran-comment-line-start-skip)
1473 (if fortran-comment-indent-style 1426 (if fortran-comment-indent-style
1474 (let ((char (if (stringp fortran-comment-indent-char) 1427 (let* ((char (if (stringp fortran-comment-indent-char)
1475 (aref fortran-comment-indent-char 0) 1428 (aref fortran-comment-indent-char 0)
1476 fortran-comment-indent-char))) 1429 fortran-comment-indent-char))
1430 (chars (string ? ?\t char)))
1477 (goto-char (match-end 0)) 1431 (goto-char (match-end 0))
1478 (delete-horizontal-regexp (concat " \t" (char-to-string char))) 1432 (skip-chars-backward chars)
1433 (delete-region (point) (progn (skip-chars-forward chars)
1434 (point)))
1479 (insert-char char (- col (current-column))))) 1435 (insert-char char (- col (current-column)))))
1480 (if (looking-at "\t[1-9]") 1436 (if (looking-at "\t[1-9]")
1481 (if indent-tabs-mode 1437 (if indent-tabs-mode
1482 (goto-char (match-end 0)) 1438 (goto-char (match-end 0))
1483 (delete-char 2) 1439 (delete-char 2)
1484 (insert " ") 1440 (insert-char ? 5)
1485 (insert fortran-continuation-string)) 1441 (insert fortran-continuation-string))
1486 (if (looking-at " [^ 0\n]") 1442 (if (looking-at " [^ 0\n]")
1487 (if indent-tabs-mode 1443 (if indent-tabs-mode
1488 (progn (delete-char 6) 1444 (progn (delete-char 6)
1489 (insert "\t") 1445 (insert ?\t (fortran-numerical-continuation-char) 1))
1490 (insert-char (fortran-numerical-continuation-char) 1))
1491 (forward-char 6)) 1446 (forward-char 6))
1492 (delete-horizontal-space) 1447 (delete-horizontal-space)
1493 ;; Put line number in columns 0-4 1448 ;; Put line number in columns 0-4
1494 ;; or put continuation character in column 5. 1449 ;; or put continuation character in column 5.
1495 (cond ((eobp)) 1450 (cond ((eobp))
1516 (indent-to col) 1471 (indent-to col)
1517 ;; Indent any comment following code on the same line. 1472 ;; Indent any comment following code on the same line.
1518 (if (and comment-start-skip 1473 (if (and comment-start-skip
1519 (fortran-find-comment-start-skip)) 1474 (fortran-find-comment-start-skip))
1520 (progn (goto-char (match-beginning 0)) 1475 (progn (goto-char (match-beginning 0))
1521 (if (not (= (current-column) (fortran-comment-hook))) 1476 (if (not (= (current-column)
1477 (fortran-comment-indent-function)))
1522 (progn (delete-horizontal-space) 1478 (progn (delete-horizontal-space)
1523 (indent-to (fortran-comment-hook))))))))) 1479 (indent-to
1480 (fortran-comment-indent-function)))))))))
1524 1481
1525 (defun fortran-line-number-indented-correctly-p () 1482 (defun fortran-line-number-indented-correctly-p ()
1526 "Return t if current line's line number is correctly indented. 1483 "Return t if current line's line number is correctly indented.
1527 Do not call if there is no line number." 1484 Do not call if there is no line number."
1528 (save-excursion 1485 (save-excursion
1534 (= (current-column) 5)))))) 1491 (= (current-column) 5))))))
1535 1492
1536 (defun fortran-check-for-matching-do () 1493 (defun fortran-check-for-matching-do ()
1537 "When called from a numbered statement, return t if matching DO is found. 1494 "When called from a numbered statement, return t if matching DO is found.
1538 Otherwise return nil." 1495 Otherwise return nil."
1539 (let (charnum 1496 (let ((case-fold-search t)
1540 (case-fold-search t)) 1497 charnum)
1541 (save-excursion 1498 (save-excursion
1542 (beginning-of-line) 1499 (beginning-of-line)
1543 (if (looking-at "[ \t]*[0-9]+") 1500 (if (looking-at "[ \t]*[0-9]+")
1544 (progn 1501 (progn
1545 (skip-chars-forward " \t") 1502 (skip-chars-forward " \t")
1546 (skip-chars-forward "0") ;skip past leading zeros 1503 (skip-chars-forward "0") ;skip past leading zeros
1547 (setq charnum (buffer-substring (point) 1504 (setq charnum
1548 (progn (skip-chars-forward "0-9") 1505 (buffer-substring (point) (progn
1549 (point)))) 1506 (skip-chars-forward "0-9")
1507 (point))))
1550 (beginning-of-line) 1508 (beginning-of-line)
1551 (fortran-with-subprogram-narrowing 1509 (fortran-with-subprogram-narrowing
1552 (and (re-search-backward 1510 (and (re-search-backward
1553 (concat "\\(^[ \t0-9]*do[ \t]*0*" charnum "\\b\\)\\|" 1511 (concat "\\(^[ \t0-9]*do[ \t]*0*" charnum "\\b\\)\\|"
1554 "\\(^[ \t]*0*" charnum "\\b\\)") 1512 "\\(^[ \t]*0*" charnum "\\b\\)")
1562 ;; one uses a lot of save-excursions. Note that re-search-forward 1520 ;; one uses a lot of save-excursions. Note that re-search-forward
1563 ;; moves point even if comment-start-skip is inside a string-constant. 1521 ;; moves point even if comment-start-skip is inside a string-constant.
1564 ;; Some code expects certain values for match-beginning and end 1522 ;; Some code expects certain values for match-beginning and end
1565 (interactive) 1523 (interactive)
1566 (if (save-excursion 1524 (if (save-excursion
1567 (re-search-forward comment-start-skip 1525 (re-search-forward comment-start-skip (line-end-position) t))
1568 (save-excursion (end-of-line) (point)) t))
1569 (let ((save-match-beginning (match-beginning 0)) 1526 (let ((save-match-beginning (match-beginning 0))
1570 (save-match-end (match-end 0))) 1527 (save-match-end (match-end 0)))
1571 (if (fortran-is-in-string-p (match-beginning 0)) 1528 (if (fortran-is-in-string-p (match-beginning 0))
1572 (save-excursion 1529 (save-excursion
1573 (goto-char save-match-end) 1530 (goto-char save-match-end)
1574 (fortran-find-comment-start-skip)) ; recurse for rest of line 1531 (fortran-find-comment-start-skip)) ; recurse for rest of line
1575 (goto-char save-match-beginning) 1532 (goto-char save-match-beginning)
1576 (re-search-forward comment-start-skip 1533 (re-search-forward comment-start-skip (line-end-position) t)
1577 (save-excursion (end-of-line) (point)) t)
1578 (goto-char (match-end 0)) 1534 (goto-char (match-end 0))
1579 t)) 1535 t))
1580 nil)) 1536 nil))
1581 1537
1582 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel) 1538 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel)
1587 (goto-char where) 1543 (goto-char where)
1588 (cond 1544 (cond
1589 ((bolp) nil) ; bol is never inside a string 1545 ((bolp) nil) ; bol is never inside a string
1590 ((save-excursion ; comment lines too 1546 ((save-excursion ; comment lines too
1591 (beginning-of-line) 1547 (beginning-of-line)
1592 (looking-at comment-line-start-skip)) nil) 1548 (looking-at fortran-comment-line-start-skip)) nil)
1593 (t (let (;; ok, serious now. Init some local vars: 1549 (t (let (;; ok, serious now. Init some local vars:
1594 (parse-state '(0 nil nil nil nil nil 0)) 1550 (parse-state '(0 nil nil nil nil nil 0))
1595 (quoted-comment-start (if comment-start 1551 (quoted-comment-start (if comment-start
1596 (regexp-quote comment-start))) 1552 (regexp-quote comment-start)))
1597 (not-done t) 1553 (not-done t)
1598 parse-limit 1554 parse-limit end-of-line)
1599 end-of-line
1600 )
1601 ;; move to start of current statement 1555 ;; move to start of current statement
1602 (fortran-next-statement) 1556 (fortran-next-statement)
1603 (fortran-previous-statement) 1557 (fortran-previous-statement)
1604 ;; now parse up to WHERE 1558 ;; now parse up to WHERE
1605 (while not-done 1559 (while not-done
1606 (if (or ;; skip to next line if: 1560 (if (or ;; skip to next line if:
1607 ;; - comment line? 1561 ;; - comment line?
1608 (looking-at comment-line-start-skip) 1562 (looking-at fortran-comment-line-start-skip)
1609 ;; - at end of line? 1563 ;; - at end of line?
1610 (eolp) 1564 (eolp)
1611 ;; - not in a string and after comment-start? 1565 ;; - not in a string and after comment-start?
1612 (and (not (nth 3 parse-state)) 1566 (and (not (nth 3 parse-state))
1613 comment-start 1567 comment-start
1624 ((and (< (current-column) 5) 1578 ((and (< (current-column) 5)
1625 (equal fortran-continuation-string 1579 (equal fortran-continuation-string
1626 (char-to-string (following-char))) 1580 (char-to-string (following-char)))
1627 (forward-char 1)))) 1581 (forward-char 1))))
1628 ;; find out parse-limit from here 1582 ;; find out parse-limit from here
1629 (setq end-of-line (save-excursion (end-of-line)(point))) 1583 (setq end-of-line (line-end-position))
1630 (setq parse-limit (min where end-of-line)) 1584 (setq parse-limit (min where end-of-line))
1631 ;; parse max up to comment-start, if non-nil and in current line 1585 ;; parse max up to comment-start, if non-nil and in current line
1632 (if comment-start 1586 (if comment-start
1633 (save-excursion 1587 (save-excursion
1634 (if (re-search-forward quoted-comment-start end-of-line t) 1588 (if (re-search-forward quoted-comment-start end-of-line t)
1635 (setq parse-limit (min (point) parse-limit))))) 1589 (setq parse-limit (min (point) parse-limit)))))
1636 ;; now parse if still in limits 1590 ;; now parse if still in limits
1637 (if (< (point) where) 1591 (if (< (point) where)
1638 (setq parse-state (parse-partial-sexp 1592 (setq parse-state (parse-partial-sexp
1639 (point) parse-limit nil nil parse-state)) 1593 (point) parse-limit nil nil parse-state))
1640 (setq not-done nil)) 1594 (setq not-done nil))))
1641 ))
1642 ;; result is 1595 ;; result is
1643 (nth 3 parse-state)))))) 1596 (nth 3 parse-state))))))
1644 1597
1645 (defun fortran-auto-fill-mode (arg) 1598 (defun fortran-auto-fill-mode (arg)
1646 "Toggle fortran-auto-fill mode. 1599 "Toggle fortran-auto-fill mode.
1659 (defun fortran-do-auto-fill () 1612 (defun fortran-do-auto-fill ()
1660 (if (> (current-column) fill-column) 1613 (if (> (current-column) fill-column)
1661 (fortran-indent-line))) 1614 (fortran-indent-line)))
1662 1615
1663 (defun fortran-fill () 1616 (defun fortran-fill ()
1664 (interactive)
1665 (let* ((auto-fill-function #'fortran-do-auto-fill) 1617 (let* ((auto-fill-function #'fortran-do-auto-fill)
1666 (opoint (point)) 1618 (opoint (point))
1667 (bol (save-excursion (beginning-of-line) (point))) 1619 (bol (line-beginning-position))
1668 (eol (save-excursion (end-of-line) (point))) 1620 (eol (line-end-position))
1669 (bos (min eol (+ bol (fortran-current-line-indentation)))) 1621 (bos (min eol (+ bol (fortran-current-line-indentation))))
1670 (quote 1622 (quote
1671 (save-excursion 1623 (save-excursion
1672 (goto-char bol) 1624 (goto-char bol)
1673 (if (looking-at comment-line-start-skip) 1625 (if (looking-at fortran-comment-line-start-skip)
1674 nil ; OK to break quotes on comment lines. 1626 nil ; OK to break quotes on comment lines.
1675 (move-to-column fill-column) 1627 (move-to-column fill-column)
1676 (if (fortran-is-in-string-p (point)) 1628 (if (fortran-is-in-string-p (point))
1677 (save-excursion (re-search-backward "\\S\"\\s\"\\S\"" bol t) 1629 (save-excursion (re-search-backward "\\S\"\\s\"\\S\"" bol t)
1678 (if fortran-break-before-delimiters 1630 (if fortran-break-before-delimiters
1720 (< (current-column) (1+ fill-column))))) 1672 (< (current-column) (1+ fill-column)))))
1721 (save-excursion 1673 (save-excursion
1722 (goto-char fill-point) 1674 (goto-char fill-point)
1723 (bolp)))) 1675 (bolp))))
1724 (if (> (save-excursion 1676 (if (> (save-excursion
1725 (goto-char fill-point) (current-column)) 1677 (goto-char fill-point)
1678 (current-column))
1726 (1+ fill-column)) 1679 (1+ fill-column))
1727 (progn (goto-char fill-point) 1680 (progn (goto-char fill-point)
1728 (fortran-break-line)) 1681 (fortran-break-line))
1729 (save-excursion 1682 (save-excursion
1730 (if (> (save-excursion 1683 (if (> (save-excursion
1731 (goto-char fill-point) 1684 (goto-char fill-point)
1732 (current-column)) 1685 (current-column))
1733 (+ (fortran-calculate-indent) fortran-continuation-indent)) 1686 (+ (fortran-calculate-indent) fortran-continuation-indent))
1734 (progn 1687 (progn
1735 (goto-char fill-point) 1688 (goto-char fill-point)
1736 (fortran-break-line)))))) 1689 (fortran-break-line))))))))
1737 )) 1690
1738 (defun fortran-break-line () 1691 (defun fortran-break-line ()
1739 (let ((opoint (point)) 1692 (let ((opoint (point))
1740 (bol (save-excursion (beginning-of-line) (point))) 1693 (bol (line-beginning-position))
1741 (eol (save-excursion (end-of-line) (point))) 1694 (eol (line-end-position))
1742 (comment-string nil)) 1695 (comment-string nil))
1743
1744 (save-excursion 1696 (save-excursion
1745 (if (and comment-start-skip (fortran-find-comment-start-skip)) 1697 (if (and comment-start-skip (fortran-find-comment-start-skip))
1746 (progn 1698 (progn
1747 (re-search-backward comment-start-skip bol t) 1699 (re-search-backward comment-start-skip bol t)
1748 (setq comment-string (buffer-substring (point) eol)) 1700 (setq comment-string (buffer-substring (point) eol))
1749 (delete-region (point) eol)))) 1701 (delete-region (point) eol))))
1750 ;; Forward line 1 really needs to go to next non white line 1702 ;; Forward line 1 really needs to go to next non white line
1751 (if (save-excursion (forward-line) 1703 (if (save-excursion (forward-line)
1752 (or (looking-at " [^ 0\n]") 1704 (or (looking-at " [^ 0\n]\\|\t[1-9]")))
1753 (looking-at "\t[1-9]")))
1754 (progn 1705 (progn
1755 (end-of-line) 1706 (end-of-line)
1756 (delete-region (point) (match-end 0)) 1707 (delete-region (point) (match-end 0))
1757 (delete-horizontal-space) 1708 (delete-horizontal-space)
1758 (fortran-fill)) 1709 (fortran-fill))
1760 (if comment-string 1711 (if comment-string
1761 (save-excursion 1712 (save-excursion
1762 (goto-char bol) 1713 (goto-char bol)
1763 (end-of-line) 1714 (end-of-line)
1764 (delete-horizontal-space) 1715 (delete-horizontal-space)
1765 (indent-to (fortran-comment-hook)) 1716 (indent-to (fortran-comment-indent-function))
1766 (insert comment-string))))) 1717 (insert comment-string)))))
1767 1718
1768 (defun fortran-analyze-file-format () 1719 (defun fortran-analyze-file-format ()
1769 "Return nil if fixed format is used, t if TAB formatting is used. 1720 "Return nil if fixed format is used, t if TAB formatting is used.
1770 Use `fortran-tab-mode-default' if no non-comment statements are found in the 1721 Use `fortran-tab-mode-default' if no non-comment statements are found in the
1773 (save-excursion 1724 (save-excursion
1774 (goto-char (point-min)) 1725 (goto-char (point-min))
1775 (setq i 0) 1726 (setq i 0)
1776 (while (not (or 1727 (while (not (or
1777 (eobp) 1728 (eobp)
1778 (looking-at "\t") 1729 (eq (char-after) ?\t)
1779 (looking-at " ") 1730 (looking-at " ")
1780 (> i fortran-analyze-depth))) 1731 (> i fortran-analyze-depth)))
1781 (forward-line) 1732 (forward-line)
1782 (setq i (1+ i))) 1733 (setq i (1+ i)))
1783 (cond 1734 (cond
1784 ((looking-at "\t") t) 1735 ((eq (char-after) ?\t) t)
1785 ((looking-at " ") nil) 1736 ((looking-at " ") nil)
1786 (fortran-tab-mode-default t) 1737 (fortran-tab-mode-default t)
1787 (t nil))))) 1738 (t nil)))))
1788 1739
1789 (or (assq 'fortran-tab-mode-string minor-mode-alist) 1740 (or (assq 'fortran-tab-mode-string minor-mode-alist)
1803 (fortran-fill-statement) 1754 (fortran-fill-statement)
1804 ;; We're in a comment block. Find the start and end of a 1755 ;; We're in a comment block. Find the start and end of a
1805 ;; paragraph, delimited either by non-comment lines or empty 1756 ;; paragraph, delimited either by non-comment lines or empty
1806 ;; comments. (Get positions as markers, since the 1757 ;; comments. (Get positions as markers, since the
1807 ;; `indent-region' below can shift the block's end). 1758 ;; `indent-region' below can shift the block's end).
1808 (let* ((non-empty-comment (concat "\\(" comment-line-start-skip 1759 (let* ((non-empty-comment (concat "\\(" fortran-comment-line-start-skip
1809 "\\)" "[^ \t\n]")) 1760 "\\)" "[^ \t\n]"))
1810 (start (save-excursion 1761 (start (save-excursion
1811 ;; Find (start of) first line. 1762 ;; Find (start of) first line.
1812 (while (and (zerop (forward-line -1)) 1763 (while (and (zerop (forward-line -1))
1813 (looking-at non-empty-comment))) 1764 (looking-at non-empty-comment)))
1823 ;; comment start skip and use that as a fill-prefix for 1774 ;; comment start skip and use that as a fill-prefix for
1824 ;; filling the region. 1775 ;; filling the region.
1825 (indent-region start end nil) 1776 (indent-region start end nil)
1826 (let ((paragraph-ignore-fill-prefix nil) 1777 (let ((paragraph-ignore-fill-prefix nil)
1827 (fill-prefix (progn (beginning-of-line) 1778 (fill-prefix (progn (beginning-of-line)
1828 (looking-at comment-line-start-skip) 1779 (looking-at fortran-comment-line-start-skip)
1829 (match-string 0)))) 1780 (match-string 0))))
1830 (let (fill-paragraph-function) 1781 (let (fill-paragraph-function)
1831 (fill-region start end justify))) ; with normal `fill-paragraph' 1782 (fill-region start end justify))) ; with normal `fill-paragraph'
1832 (set-marker start nil) 1783 (set-marker start nil)
1833 (set-marker end nil)))) 1784 (set-marker end nil))))
1838 (interactive) 1789 (interactive)
1839 (let ((auto-fill-function #'fortran-do-auto-fill)) 1790 (let ((auto-fill-function #'fortran-do-auto-fill))
1840 (if (not (save-excursion 1791 (if (not (save-excursion
1841 (beginning-of-line) 1792 (beginning-of-line)
1842 (or (looking-at "[ \t]*$") 1793 (or (looking-at "[ \t]*$")
1843 (looking-at comment-line-start-skip) 1794 (looking-at fortran-comment-line-start-skip)
1844 (and comment-start-skip 1795 (and comment-start-skip
1845 (looking-at (concat "[ \t]*" comment-start-skip)))))) 1796 (looking-at (concat "[ \t]*" comment-start-skip))))))
1846 (save-excursion 1797 (save-excursion
1847 ;; Find beginning of statement. 1798 ;; Find beginning of statement.
1848 (fortran-next-statement) 1799 (fortran-next-statement)