aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Love1999-11-23 20:19:47 +0000
committerDave Love1999-11-23 20:19:47 +0000
commit7dae727d72f9f7618bd8a27f416a0660d93c9e6b (patch)
treeec5e7ebdb1dabcf3756587d427e20ec5e23c8763
parentd8f479c6d26566a68c2c01e1adfd89815ec2e78b (diff)
downloademacs-7dae727d72f9f7618bd8a27f416a0660d93c9e6b.tar.gz
emacs-7dae727d72f9f7618bd8a27f416a0660d93c9e6b.zip
(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.
-rw-r--r--lisp/progmodes/fortran.el403
1 files changed, 177 insertions, 226 deletions
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index 120a885d017..bda9585f7b6 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -44,15 +44,11 @@
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
@@ -125,13 +121,15 @@ Fortran indentation plus `fortran-comment-line-extra-indent'."
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
@@ -301,7 +299,6 @@ These get fixed-format comments fontified.")
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
@@ -309,43 +306,33 @@ These get fixed-format comments fontified.")
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(/]*\\(*\\)?")
@@ -365,21 +352,17 @@ These get fixed-format comments fontified.")
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)
@@ -417,10 +400,10 @@ These get fixed-format comments fontified.")
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)
@@ -447,7 +430,15 @@ These get fixed-format comments fontified.")
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]
@@ -459,10 +450,10 @@ These get fixed-format comments fontified.")
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]
@@ -480,11 +471,8 @@ These get fixed-format comments fontified.")
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
@@ -555,6 +543,11 @@ These get fixed-format comments fontified.")
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.
@@ -620,7 +613,7 @@ Variables controlling indentation style and extra features:
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
626Turning on Fortran mode calls the value of the variable `fortran-mode-hook' 619Turning on Fortran mode calls the value of the variable `fortran-mode-hook'
@@ -636,7 +629,7 @@ with no args, if that value is non-nil."
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)
@@ -644,12 +637,12 @@ with no args, if that value is non-nil."
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)
@@ -685,7 +678,7 @@ with no args, if that value is non-nil."
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))
@@ -701,15 +694,15 @@ 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,
@@ -717,16 +710,16 @@ or on a new line inserted before this line if this line is not 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)
@@ -844,10 +837,12 @@ See also `fortran-window-create'."
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
@@ -884,14 +879,6 @@ plus one. Otherwise return 1. Zero not allowed."
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.
889CHARS is like the inside of a [...] in a regular expression
890except 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.
@@ -904,21 +891,18 @@ Auto-indent does not happen if a numeric ARG is used."
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))
@@ -946,7 +930,7 @@ Auto-indent does not happen if a numeric ARG is used."
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
@@ -958,7 +942,7 @@ Auto-indent does not happen if a numeric ARG is used."
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
@@ -976,13 +960,13 @@ Auto-indent does not happen if a numeric ARG is used."
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.
981The marks are pushed." 965The 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.
@@ -993,16 +977,13 @@ non-comment Fortran statement in the file, and nil otherwise."
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))
@@ -1022,10 +1003,8 @@ non-comment Fortran statement in the file, and nil otherwise."
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)))
@@ -1035,7 +1014,7 @@ non-comment Fortran statement in the file, and nil otherwise."
1035The subprogram visible is the one that contains or follows point." 1014The 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)
@@ -1044,67 +1023,50 @@ 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.
1035Use 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.
@@ -1114,7 +1076,6 @@ The marks are pushed."
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)))))
@@ -1131,18 +1092,18 @@ Return point or nil."
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
@@ -1150,27 +1111,27 @@ Return point or nil."
1150 "Search backwards for first unmatched DO [WHILE]. 1111 "Search backwards for first unmatched DO [WHILE].
1151Return point or nil." 1112Return 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
@@ -1202,34 +1163,30 @@ Return point or nil."
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
@@ -1238,10 +1195,11 @@ Return point or nil."
1238Return point or nil." 1195Return 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")
@@ -1254,8 +1212,7 @@ Return point or nil."
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
@@ -1266,12 +1223,11 @@ Return point or nil."
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
@@ -1279,20 +1235,18 @@ Return point or nil."
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
@@ -1307,14 +1261,15 @@ Return point or nil."
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)))
@@ -1331,7 +1286,7 @@ Return point or nil."
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."))
@@ -1357,10 +1312,10 @@ Return point or nil."
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))))
@@ -1379,7 +1334,8 @@ Return point or nil."
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))
@@ -1388,7 +1344,7 @@ Return point or nil."
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)
@@ -1398,8 +1354,7 @@ Return point or nil."
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))
@@ -1441,19 +1396,17 @@ For comment lines, returns indentation of the first
1441non-indentation text within the comment." 1396non-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)))
@@ -1469,25 +1422,27 @@ notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
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
@@ -1518,9 +1473,11 @@ notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
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.
@@ -1536,17 +1493,18 @@ Do not call if there is no line number."
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.
1538Otherwise return nil." 1495Otherwise 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
@@ -1564,8 +1522,7 @@ Return t if `comment-start-skip' found, nil if not."
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))
@@ -1573,8 +1530,7 @@ Return t if `comment-start-skip' found, nil if not."
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))
@@ -1589,15 +1545,13 @@ Return t if `comment-start-skip' found, nil if not."
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)
@@ -1605,7 +1559,7 @@ Return t if `comment-start-skip' found, nil if not."
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?
@@ -1626,7 +1580,7 @@ Return t if `comment-start-skip' found, nil if not."
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
@@ -1637,8 +1591,7 @@ Return t if `comment-start-skip' found, nil if not."
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
@@ -1661,16 +1614,15 @@ automatically breaks the line at a previous space."
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))
@@ -1722,7 +1674,8 @@ automatically breaks the line at a previous space."
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))
@@ -1733,14 +1686,13 @@ automatically breaks the line at a previous space."
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
@@ -1749,8 +1701,7 @@ automatically breaks the line at a previous space."
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))
@@ -1762,7 +1713,7 @@ automatically breaks the line at a previous space."
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 ()
@@ -1775,13 +1726,13 @@ file before the end or the first `fortran-analyze-depth' lines."
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)))))
@@ -1805,7 +1756,7 @@ Intended as the value of `fill-paragraph-function'."
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.
@@ -1825,7 +1776,7 @@ Intended as the value of `fill-paragraph-function'."
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'
@@ -1840,7 +1791,7 @@ Intended as the value of `fill-paragraph-function'."
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