diff options
| author | Richard M. Stallman | 1994-12-18 21:20:07 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-12-18 21:20:07 +0000 |
| commit | c5af0a1823ebdb1d15aaa043fe210fd35b78fc66 (patch) | |
| tree | b061225a2f01339f01d9888771b32ef077886e09 | |
| parent | fef5a0becfec44cf93f5ce02a8df0d959d9714db (diff) | |
| download | emacs-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.el | 275 |
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. |
| 115 | Also, from an ENDDO statement, blink on matching DO [WHILE] statement.") | 115 | Also, 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. | ||
| 800 | The 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. | ||
| 862 | The 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." |