aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1994-12-18 21:20:07 +0000
committerRichard M. Stallman1994-12-18 21:20:07 +0000
commitc5af0a1823ebdb1d15aaa043fe210fd35b78fc66 (patch)
treeb061225a2f01339f01d9888771b32ef077886e09
parentfef5a0becfec44cf93f5ce02a8df0d959d9714db (diff)
downloademacs-c5af0a1823ebdb1d15aaa043fe210fd35b78fc66.tar.gz
emacs-c5af0a1823ebdb1d15aaa043fe210fd35b78fc66.zip
(fortran-end-if, fortran-end-do,
fortran-beginning-if, fortran-beginning-do): New subroutines. (fortran-blink-matching-if, fortran-blink-matching-do): Use them. (fortran-mark-do, fortran-mark-if): New user functions. (fortran-blink-matching-if, fortran-mode): Doc mod.
-rw-r--r--lisp/progmodes/fortran.el275
1 files changed, 208 insertions, 67 deletions
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index f177afee57a..c3c32e47fe4 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Michael D. Prange <prange@erl.mit.edu> 5;; Author: Michael D. Prange <prange@erl.mit.edu>
6;; Maintainer: bug-fortran-mode@erl.mit.edu 6;; Maintainer: bug-fortran-mode@erl.mit.edu
7;; Version 1.30.5 (May 20, 1994) 7;; Version 1.30.5.1 (Sept 16, 1994)
8;; Keywords: languages 8;; Keywords: languages
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -46,7 +46,7 @@
46 46
47;;; Bugs to bug-fortran-mode@erl.mit.edu 47;;; Bugs to bug-fortran-mode@erl.mit.edu
48 48
49(defconst fortran-mode-version "version 1.30.5") 49(defconst fortran-mode-version "version 1.30.5.1")
50 50
51;;; Code: 51;;; Code:
52 52
@@ -111,8 +111,8 @@ Normally a space.")
111 "*Non-nil causes all numbered lines to be treated as possible DO loop ends.") 111 "*Non-nil causes all numbered lines to be treated as possible DO loop ends.")
112 112
113(defvar fortran-blink-matching-if nil 113(defvar fortran-blink-matching-if nil
114 "*From a Fortran ENDIF statement, blink the matching IF statement. 114 "*Non-nil causes \\[fortran-indent-line] on ENDIF statement to blink on matching IF.
115Also, from an ENDDO statement, blink on matching DO [WHILE] statement.") 115Also, from an ENDDO statement blink on matching DO [WHILE] statement.")
116 116
117(defvar fortran-continuation-string "$" 117(defvar fortran-continuation-string "$"
118 "*Single-character string used for Fortran continuation lines. 118 "*Single-character string used for Fortran continuation lines.
@@ -391,9 +391,9 @@ Variables controlling indentation style and extra features:
391 Non-nil causes all numbered lines to be treated as possible \"continue\" 391 Non-nil causes all numbered lines to be treated as possible \"continue\"
392 statements. (default nil) 392 statements. (default nil)
393 fortran-blink-matching-if 393 fortran-blink-matching-if
394 From a Fortran ENDIF statement, blink the matching IF statement. 394 Non-nil causes \\[fortran-indent-line] on an ENDIF statement to blink on
395 Also, from an ENDDO statement, blink on matching DO [WHILE] statement. 395 matching IF. Also, from an ENDDO statement, blink on matching DO [WHILE]
396 (default nil) 396 statement. (default nil)
397 fortran-continuation-string 397 fortran-continuation-string
398 Single-character string to be inserted in column 5 of a continuation 398 Single-character string to be inserted in column 5 of a continuation
399 line. (default \"$\") 399 line. (default \"$\")
@@ -747,49 +747,23 @@ non-comment Fortran statement in the file, and nil otherwise."
747 'last-statement))) 747 'last-statement)))
748 748
749(defun fortran-blink-matching-if () 749(defun fortran-blink-matching-if ()
750 "From a Fortran ENDIF statement, blink the matching IF statement." 750 ;; From a Fortran ENDIF statement, blink the matching IF statement.
751 (let ((count 1) (top-of-window (window-start)) matching-if 751 (let ((top-of-window (window-start)) matching-if
752 (endif-point (point)) message) 752 (endif-point (point)) message)
753 (if (save-excursion (beginning-of-line) 753 (if (save-excursion (beginning-of-line)
754 (skip-chars-forward " \t0-9") 754 (skip-chars-forward " \t0-9")
755 (looking-at "end[ \t]*if\\b")) 755 (looking-at "end[ \t]*if\\b"))
756 (progn 756 (progn
757 (save-excursion 757 (if (not (setq matching-if (fortran-beginning-if)))
758 (while (and (not (= count 0)) 758 (setq message "No matching if.")
759 (not (eq (fortran-previous-statement) 759 (if (< matching-if top-of-window)
760 'first-statement)) 760 (save-excursion
761 (not (looking-at 761 (goto-char matching-if)
762 "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) 762 (beginning-of-line)
763 ; Keep local to subprogram 763 (setq message
764 (skip-chars-forward " \t0-9") 764 (concat "Matches "
765 (cond ((looking-at "if[ \t]*(") 765 (buffer-substring
766 (save-excursion 766 (point) (progn (end-of-line) (point))))))))
767 (if (or
768 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
769 (let (then-test);multi-line if-then
770 (while
771 (and (= (forward-line 1) 0)
772 ;search forward for then
773 (or (looking-at " [^ 0\n]")
774 (looking-at "\t[1-9]"))
775 (not
776 (setq
777 then-test
778 (looking-at
779 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
780 then-test))
781 (setq count (- count 1)))))
782 ((looking-at "end[ \t]*if\\b")
783 (setq count (+ count 1)))))
784 (if (not (= count 0))
785 (setq message "No matching if.")
786 (if (< (point) top-of-window)
787 (setq message (concat "Matches " (buffer-substring
788 (progn (beginning-of-line)
789 (point))
790 (progn (end-of-line)
791 (point)))))
792 (setq matching-if (point)))))
793 (if message 767 (if message
794 (message "%s" message) 768 (message "%s" message)
795 (goto-char matching-if) 769 (goto-char matching-if)
@@ -799,38 +773,205 @@ non-comment Fortran statement in the file, and nil otherwise."
799(defun fortran-blink-matching-do () 773(defun fortran-blink-matching-do ()
800 ;; From a Fortran ENDDO statement, blink on the matching DO or DO WHILE 774 ;; From a Fortran ENDDO statement, blink on the matching DO or DO WHILE
801 ;; statement. This is basically copied from fortran-blink-matching-if. 775 ;; statement. This is basically copied from fortran-blink-matching-if.
802 (let ((count 1) (top-of-window (window-start)) matching-do 776 (let ((top-of-window (window-start)) matching-do
803 (enddo-point (point)) message) 777 (enddo-point (point)) message)
804 (if (save-excursion (beginning-of-line) 778 (if (save-excursion (beginning-of-line)
805 (skip-chars-forward " \t0-9") 779 (skip-chars-forward " \t0-9")
806 (looking-at "end[ \t]*do\\b")) 780 (looking-at "end[ \t]*do\\b"))
807 (progn 781 (progn
808 (save-excursion 782 (if (not (setq matching-do (fortran-beginning-do)))
809 (while (and (not (= count 0)) 783 (setq message "No matching do.")
810 (not (eq (fortran-previous-statement) 784 (if (< matching-do top-of-window)
811 'first-statement)) 785 (save-excursion
812 (not (looking-at 786 (goto-char matching-do)
813 "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) 787 (beginning-of-line)
814 ; Keep local to subprogram 788 (setq message
815 (skip-chars-forward " \t0-9") 789 (concat "Matches "
816 (cond ((looking-at "do[ \t]+[^0-9]") 790 (buffer-substring
817 (setq count (- count 1))) 791 (point) (progn (end-of-line) (point))))))))
818 ((looking-at "end[ \t]*do\\b")
819 (setq count (+ count 1)))))
820 (if (not (= count 0))
821 (setq message "No matching do")
822 (if (< (point) top-of-window)
823 (setq message (concat "Matches " (buffer-substring
824 (progn (beginning-of-line)
825 (point))
826 (progn (end-of-line)
827 (point)))))
828 (setq matching-do (point)))))
829 (if message 792 (if message
830 (message "%s" message) 793 (message "%s" message)
831 (goto-char matching-do) 794 (goto-char matching-do)
832 (sit-for 1) 795 (sit-for 1)
833 (goto-char enddo-point)))))) 796 (goto-char enddo-point))))))
797
798(defun fortran-mark-do ()
799 "Put mark at end of Fortran DO [WHILE]-ENDDO construct, point at beginning.
800The marks are pushed."
801 (interactive)
802 (let (enddo-point do-point)
803 (if (setq enddo-point (fortran-end-do))
804 (if (not (setq do-point (fortran-beginning-do)))
805 (message "No matching do.")
806 ;; Set mark, move point.
807 (goto-char enddo-point)
808 (push-mark)
809 (goto-char do-point)))))
810
811(defun fortran-end-do ()
812 ;; Search forward for first unmatched ENDDO. Return point or nil.
813 (if (save-excursion (beginning-of-line)
814 (skip-chars-forward " \t0-9")
815 (looking-at "end[ \t]*do\\b"))
816 ;; Sitting on one.
817 (match-beginning 0)
818 ;; Search for one.
819 (save-excursion
820 (let ((count 1))
821 (while (and (not (= count 0))
822 (not (eq (fortran-next-statement) 'last-statement))
823 ;; Keep local to subprogram
824 (not (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
825
826 (skip-chars-forward " \t0-9")
827 (cond ((looking-at "end[ \t]*do\\b")
828 (setq count (- count 1)))
829 ((looking-at "do[ \t]+[^0-9]")
830 (setq count (+ count 1)))))
831 (and (= count 0)
832 ;; All pairs accounted for.
833 (point))))))
834
835(defun fortran-beginning-do ()
836 ;; Search backwards for first unmatched DO [WHILE]. Return point or nil.
837 (if (save-excursion (beginning-of-line)
838 (skip-chars-forward " \t0-9")
839 (looking-at "do[ \t]+"))
840 ;; Sitting on one.
841 (match-beginning 0)
842 ;; Search for one.
843 (save-excursion
844 (let ((count 1))
845 (while (and (not (= count 0))
846 (not (eq (fortran-previous-statement) 'first-statement))
847 ;; Keep local to subprogram
848 (not (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
849
850 (skip-chars-forward " \t0-9")
851 (cond ((looking-at "do[ \t]+[^0-9]")
852 (setq count (- count 1)))
853 ((looking-at "end[ \t]*do\\b")
854 (setq count (+ count 1)))))
855
856 (and (= count 0)
857 ;; All pairs accounted for.
858 (point))))))
859
860(defun fortran-mark-if ()
861 "Put mark at end of Fortran IF-ENDIF construct, point at beginning.
862The marks are pushed."
863 (interactive)
864 (let (endif-point if-point)
865 (if (setq endif-point (fortran-end-if))
866 (if (not (setq if-point (fortran-beginning-if)))
867 (message "No matching if.")
868 ;; Set mark, move point.
869 (goto-char endif-point)
870 (push-mark)
871 (goto-char if-point)))))
872
873(defun fortran-end-if ()
874 ;; Search forwards for first unmatched ENDIF. Return point or nil.
875 (if (save-excursion (beginning-of-line)
876 (skip-chars-forward " \t0-9")
877 (looking-at "end[ \t]*if\\b"))
878 ;; Sitting on one.
879 (match-beginning 0)
880 ;; Search for one. The point has been already been moved to first
881 ;; letter on line but this should not cause troubles.
882 (save-excursion
883 (let ((count 1))
884 (while (and (not (= count 0))
885 (not (eq (fortran-next-statement) 'last-statement))
886 ;; Keep local to subprogram.
887 (not (looking-at
888 "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
889
890 (skip-chars-forward " \t0-9")
891 (cond ((looking-at "end[ \t]*if\\b")
892 (setq count (- count 1)))
893
894 ((looking-at "if[ \t]*(")
895 (save-excursion
896 (if (or
897 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
898 (let (then-test) ; Multi-line if-then.
899 (while
900 (and (= (forward-line 1) 0)
901 ;; Search forward for then.
902 (or (looking-at " [^ 0\n]")
903 (looking-at "\t[1-9]"))
904 (not
905 (setq then-test
906 (looking-at
907 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
908 then-test))
909 (setq count (+ count 1)))))))
910
911 (and (= count 0)
912 ;; All pairs accounted for.
913 (point))))))
914
915(defun fortran-beginning-if ()
916 ;; Search backwards for first unmatched IF-THEN. Return point or nil.
917 (if (save-excursion
918 ;; May be sitting on multi-line if-then statement, first move to
919 ;; beginning of current statement. Note: `fortran-previous-statement'
920 ;; moves to previous statement *unless* current statement is first
921 ;; one. Only move forward if not first-statement.
922 (if (not (eq (fortran-previous-statement) 'first-statement))
923 (fortran-next-statement))
924 (skip-chars-forward " \t0-9")
925 (and
926 (looking-at "if[ \t]*(")
927 (save-match-data
928 (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
929 ;; Multi-line if-then.
930 (let (then-test)
931 (while
932 (and (= (forward-line 1) 0)
933 ;; Search forward for then.
934 (or (looking-at " [^ 0\n]")
935 (looking-at "\t[1-9]"))
936 (not
937 (setq then-test
938 (looking-at
939 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
940 then-test)))))
941 ;; Sitting on one.
942 (match-beginning 0)
943 ;; Search for one.
944 (save-excursion
945 (let ((count 1))
946 (while (and (not (= count 0))
947 (not (eq (fortran-previous-statement) 'first-statement))
948 ;; Keep local to subprogram.
949 (not (looking-at
950 "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
951
952 (skip-chars-forward " \t0-9")
953 (cond ((looking-at "if[ \t]*(")
954 (save-excursion
955 (if (or
956 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
957 (let (then-test) ; Multi-line if-then.
958 (while
959 (and (= (forward-line 1) 0)
960 ;; Search forward for then.
961 (or (looking-at " [^ 0\n]")
962 (looking-at "\t[1-9]"))
963 (not
964 (setq then-test
965 (looking-at
966 ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
967 then-test))
968 (setq count (- count 1)))))
969 ((looking-at "end[ \t]*if\\b")
970 (setq count (+ count 1)))))
971
972 (and (= count 0)
973 ;; All pairs accounted for.
974 (point))))))
834 975
835(defun fortran-indent-line () 976(defun fortran-indent-line ()
836 "Indents current Fortran line based on its contents and on previous lines." 977 "Indents current Fortran line based on its contents and on previous lines."