Mercurial > emacs
annotate lisp/progmodes/fortran.el @ 1607:c154322a8546
* bytecomp.el: Declare unread-command-char an obsolete variable.
* vip.el (vip-escape-to-emacs, vip-prefix-arg-value,
vip-prefix-arg-com): Use unread-command-event instead of
unread-command-char; respect its new semantics.
* ebuff-menu.el (electric-buffer-list, Electric-buffer-menu-exit):
Same.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Mon, 16 Nov 1992 01:29:47 +0000 |
parents | cbed5e520f81 |
children | 2701f8d53d25 |
rev | line source |
---|---|
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
1 ;;; fortran.el --- Fortran mode for GNU Emacs |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
2 |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
3 ;;; Copyright (c) 1992 Free Software Foundation, Inc. |
845 | 4 |
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
5 ;; Author: Michael D. Prange <prange@erl.mit.edu> |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
6 ;; Maintainer: bug-fortran-mode@erl.mit.edu |
1548 | 7 ;; Version 1.28.8 |
811
e694e0879463
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
807
diff
changeset
|
8 ;; Keywords: languages |
660
08eb386dd0f3
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
584
diff
changeset
|
9 |
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
10 ;; This file is part of GNU Emacs. |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
11 |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
12 ;; GNU Emacs is free software; you can redistribute it and/or modify |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
13 ;; it under the terms of the GNU General Public License as published by |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
14 ;; the Free Software Foundation; either version 2, or (at your option) |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
15 ;; any later version. |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
16 |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
17 ;; GNU Emacs is distributed in the hope that it will be useful, |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
20 ;; GNU General Public License for more details. |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
21 |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
22 ;; You should have received a copy of the GNU General Public License |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
23 ;; along with GNU Emacs; see the file COPYING. If not, write to |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
24 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
25 |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
26 ;;; Commentary: |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
27 |
1548 | 28 ;; fortran.el version 1.28.8, November 5,1992 |
29 ;; Many contributions and valuable suggestions by | |
30 ;; Lawrence R. Dodd, Ralf Fassel, Ralph Finch, Stephen Gildea, | |
31 ;; Dr. Anil Gokhale, Ulrich Mueller, Mark Neale, Eric Prestemon, | |
32 ;; Gary Sabot and Richard Stallman. | |
33 | |
34 ;; Maintained (as of version 1.28) by Stephen A. Wood (saw@cebaf.gov) | |
35 | |
332 | 36 ;;; This version is an update of version 1.21 (Oct 1, 1985). |
1548 | 37 ;;; Updated by Stephen A. Wood (saw@cebaf.gov) to use tab format |
332 | 38 ;;; continuation control and indentation. (Digit after TAB to signify |
1548 | 39 ;;; continuation line. |
332 | 40 |
41 ;;; Notes to fortran-mode version 1.28 | |
42 ;;; 1. Fortran mode can support either fixed format or tab format. Fixed | |
43 ;;; format is where statements start in column 6 (first column is 0) | |
44 ;;; and continuation lines are denoted by a character in column 5. | |
45 ;;; In tab mode, statements follow a tab character. Continuation lines | |
46 ;;; are where the first character on a line is a tab and the second is | |
47 ;;; a digit from 1 to 9. | |
48 ;;; 2. When fortran mode is called, the buffer is analyzed to determine what | |
49 ;;; kind of formating is used. Starting at the top of the file, lines | |
50 ;;; are scanned until a line is found that begins with a tab or 6 spaces. | |
51 ;;; The mode for that buffer is then set to either tab or fixed format | |
52 ;;; based on that line. If no line starting with a tab or 6 spaces is | |
53 ;;; found before the end of the buffer or in the first 100 lines, the | |
54 ;;; mode is set from the variable `fortran-tab-mode-default'. t is tab | |
55 ;;; mode, nil is fixed format mode. By default, fixed format mode is used. | |
56 ;;; To use tabbing mode as the default, put the following line in .emacs | |
57 ;;; (setq fortran-tab-mode-default t) | |
58 ;;; This line should not be in the hook since the hook is called only | |
59 ;;; after the file is analyzed. | |
60 ;;; To force a particular mode independent of the analysis, attach | |
61 ;;; (fortran-tab-mode t) or (fortran-tab-mode nil) | |
62 ;;; to fortran-mode-hook. | |
63 ;;; 3. The command `fortran-tab-mode' will toggle between fixed and tab | |
64 ;;; formatting modes. The file will not automatically be reformatted, | |
65 ;;; but either `indent-region' or `fortran-indent-subprogram' can be | |
66 ;;; used to reformat portions of the file. | |
67 ;;; 4. Several abbreviations have been added. Abbreviation mode is turned | |
68 ;;; on by default. | |
69 ;;; 5. The routine fortran-blink-matching if has been incorporated (from | |
70 ;;; experimental version 1.27). If the variable of the same name is set | |
71 ;;; to t, the the matching if statement is blinked whenever an endif | |
72 ;;; line is indented. | |
73 ;;; 6. C-c C-w is now bound to fortran-window-create-momentarily (from | |
74 ;;; experimental version 1.27.) | |
75 ;;; 7. LFD is now bound to fortran-reindent-then-newline-and-indent. | |
76 ;;; 8. fortran-continuation-string (was fortran-continuation-char) is now | |
77 ;;; a string rather than a character. | |
78 ;;; 9. Fixed a bug from 1.21 that gave max-lisp-eval-depth exceeded when | |
79 ;;; Comments lines had !'s in them. | |
80 ;;; 10. DEC fortran recognizes a & in the first column as a continuation. | |
81 ;;; character. This mode does not recognize the & as a continuation | |
82 ;;; character. | |
83 ;;; 11. fortran-blink-matching-if still is in effect when indenting a region. | |
84 ;;; Is this a desirable effect? (It looks kind of neat) | |
85 ;;; 12. If you strike a digit and there are exactly 5 characters, all spaces | |
86 ;;; to the left of the point, the digit will be inserted in place to | |
87 ;;; serve as a continuation line marker. Similarly, if the only thing to | |
88 ;;; the left of the point is a single tab, and the last command issued | |
89 ;;; was neither fortran-indent-line (TAB) or fortran-reindent-then-newline- | |
90 ;;; and-indent (LFD), the digit is inserted as a tab format style | |
91 ;;; continuation character. | |
92 ;;; 13. Both modes should usually work with tab-width set to other than 8. | |
93 ;;; However, in tab-mode, if tab-width is less than 6, the column number | |
94 ;;; for the minimum indentation is set to 6 so that all line numbers will | |
95 ;;; have have a tab after them. This may be a bit ugly, but why would | |
96 ;;; you want to use a tab-width other than 8 anyway? | |
97 ;;; 14. When in tab mode, the fortran column ruler will not be correct if | |
98 ;;; tab-width is not 8. | |
1548 | 99 ;;; 15. Fortran-electic-line-number will work properly in overwrite-mode. |
100 ;;; Thanks to Mark Neale (mjn@jet.uk) | |
101 ;;; 16. Fixed bug in fortran-previous-statement that gives "Incomplete | |
102 ;;; continuation statement." when used on the first statement which | |
103 ;;; happens to be a comment that begins with the same character as | |
104 ;;; `fortran-continuation-string' | |
105 ;;; 17. If `comment-start-skip' is found in a fortran string, no indenting is | |
106 ;;; done. Thanks to Ralf Fassel (ralf@up3aud1.gwdg.de) for patches. | |
107 ;;; This awaits a hopeful future multimode solution in which | |
108 ;;; indentation/spacing inside of constants doesn't get touched when | |
109 ;;; comment delimeter characters happen to be inside the constant. | |
110 ;;; 18. Changed meaning of `fortran-comment-line-column'. If | |
111 ;;; If `fortran-comment-indent-style' is 'fixed, then, comments are | |
112 ;;; indented to `fortran-minimum-statement-indent' plus | |
113 ;;; `fortran-comment-line-column'. If the style is `relative', the | |
114 ;;; meaning remains the same in that the line-column value is added to | |
115 ;;; the current indentation level. The default value is now zero. | |
116 ;;; (Thanks to Ulrich Mueller (ulm@vsnhd1.cern.ch). | |
117 ;;; 19. Fixed infinite loop in fortran-next-statement that occurs with emacs | |
118 ;;; versions 18.55 and before because of a difference in the behavior | |
119 ;;; of (forward-line 1) on a line that is the last in the buffer which | |
120 ;;; doesn't have a newline. (Thanks to Ulrich Mueller) | |
121 ;;; 20. Added indentation for structure, union and map blocks (Fortran 90 | |
122 ;;; and other post f77 fortrans.) at the suggestion of Dr. Anil Gokhale | |
123 ;;; (avg@dynsim1.litwin.com). | |
124 ;;; 21. The command fortran-auto-fill-mode toggles on and off fortran-auto-fill | |
125 ;;; mode. By default it is off, and the fill column is 72. (Thanks to | |
126 ;;; (Mark Neale for the code for auto fill.) Will split line before | |
127 ;;; whitespace, commas, or operators. Won't break stuff betweek quotes, | |
128 ;;; unless it is a comment line. Put (fortran-auto-fill-mode 1) into | |
129 ;;; fortran-mode-hook to have auto fill mode automatically on. | |
130 ;;; 22. If auto-fill-mode is on, fortran-indent-line will call the auto fill | |
131 ;;; code to make sure that lines are not to long after indentation. This | |
132 ;;; suggestion and improvements to auto filling provided by Eric Prestemon | |
133 ;;; (ecprest@pocorvares.er.usgs.gov. | |
134 ;;; 23. comment-line-start-skip treats cpp directives (beginning with #) as | |
135 ;;; unindentable comments. | |
136 ;;; 24. where, elsewhere indenting now supported for F90. | |
137 ;;; | |
332 | 138 |
139 ;;; Bugs to bug-fortran-mode@erl.mit.edu | |
140 | |
1548 | 141 (defconst fortran-mode-version "version 1.28.8") |
142 | |
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
143 ;;; Code: |
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
778
diff
changeset
|
144 |
332 | 145 ;;;###autoload |
146 (defvar fortran-tab-mode-default nil | |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
147 "*Default tabbing/carriage control style for empty files in Fortran mode. |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
148 A value of t specifies tab-digit style of continuation control. |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
149 A value of nil specifies that continuation lines are marked |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
150 with a character in column 6.") |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
151 |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
152 (defvar fortran-tab-mode nil |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
153 "*tabbing/carriage control style for Fortran mode. |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
154 A value of t specifies tab-digit style of continuation control. |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
155 A value of nil specifies that continuation lines are marked |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
156 with a character in column 6.") |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
157 |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
158 ;; Buffer local, used to display mode line. |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
159 (defvar fortran-tab-mode-string) |
332 | 160 |
161 (defvar fortran-do-indent 3 | |
1548 | 162 "*Extra indentation applied to DO blocks.") |
332 | 163 |
164 (defvar fortran-if-indent 3 | |
1548 | 165 "*Extra indentation applied to IF blocks.") |
166 | |
167 (defvar fortran-structure-indent 3 | |
168 "*Extra indentation applied to STRUCTURE, UNION and MAP blocks.") | |
332 | 169 |
170 (defvar fortran-continuation-indent 5 | |
1548 | 171 "*Extra indentation applied to Fortran continuation lines.") |
332 | 172 |
173 (defvar fortran-comment-indent-style 'fixed | |
174 "*nil forces comment lines not to be touched, | |
1548 | 175 'fixed produces fixed comment indentation to `fortran-comment-line-column' |
176 beyond `fortran-minimum-statement-indent', and 'relative indents to current | |
177 Fortran indentation plus `fortran-comment-line-column'.") | |
332 | 178 |
1548 | 179 (defvar fortran-comment-line-column 0 |
180 "*Amount of extra indentation for text within full-line comments.") | |
332 | 181 |
182 (defvar comment-line-start nil | |
183 "*Delimiter inserted to start new full-line comment.") | |
184 | |
185 (defvar comment-line-start-skip nil | |
186 "*Regexp to match the start of a full-line comment.") | |
187 | |
188 (defvar fortran-minimum-statement-indent 6 | |
1548 | 189 "*Minimum indentation for Fortran statements.") |
332 | 190 |
191 ;; Note that this is documented in the v18 manuals as being a string | |
192 ;; of length one rather than a single character. | |
193 ;; The code in this file accepts either format for compatibility. | |
194 (defvar fortran-comment-indent-char " " | |
195 "*Single-character string inserted for Fortran comment indentation. | |
196 Normally a space.") | |
197 | |
198 (defvar fortran-line-number-indent 1 | |
199 "*Maximum indentation for Fortran line numbers. | |
200 5 means right-justify them within their five-column field.") | |
201 | |
202 (defvar fortran-check-all-num-for-matching-do nil | |
1548 | 203 "*Non-nil causes all numbered lines to be treated as possible DO loop ends.") |
332 | 204 |
205 (defvar fortran-blink-matching-if nil | |
1548 | 206 "*From a Fortran ENDIF statement, blink the matching IF statement.") |
332 | 207 |
208 (defvar fortran-continuation-string "$" | |
1548 | 209 "*Single-character string used for Fortran continuation lines. |
332 | 210 In fixed format continuation style, this character is inserted in |
211 column 6 by \\[fortran-split-line] to begin a continuation line. | |
212 Also, if \\[fortran-indent-line] finds this at the beginning of a line, it will | |
213 convert the line into a continuation line of the appropriate style. | |
214 Normally $.") | |
215 | |
216 (defvar fortran-comment-region "c$$$" | |
217 "*String inserted by \\[fortran-comment-region]\ | |
218 at start of each line in region.") | |
219 | |
220 (defvar fortran-electric-line-number t | |
221 "*Non-nil causes line number digits to be moved to the correct column as\ | |
222 typed.") | |
223 | |
224 (defvar fortran-startup-message t | |
225 "*Non-nil displays a startup message when Fortran mode is first called.") | |
226 | |
227 (defvar fortran-column-ruler " " | |
228 "*String displayed above current line by \\[fortran-column-ruler].") | |
229 | |
230 (defconst bug-fortran-mode "bug-fortran-mode@erl.mit.edu" | |
231 "Address of mailing list for Fortran mode bugs.") | |
232 | |
233 (defvar fortran-mode-syntax-table nil | |
234 "Syntax table in use in Fortran mode buffers.") | |
235 | |
236 (defvar fortran-analyze-depth 100 | |
237 "Number of lines to scan to determine whether to use fixed or tab format\ | |
238 style.") | |
239 | |
1548 | 240 (defvar fortran-break-before-delimiters t |
241 "*Non-nil causes `fortran-do-auto-fill' to break lines before delimeters.") | |
242 | |
332 | 243 (if fortran-mode-syntax-table |
244 () | |
245 (setq fortran-mode-syntax-table (make-syntax-table)) | |
246 (modify-syntax-entry ?\; "w" fortran-mode-syntax-table) | |
247 (modify-syntax-entry ?\r " " fortran-mode-syntax-table) | |
248 (modify-syntax-entry ?+ "." fortran-mode-syntax-table) | |
249 (modify-syntax-entry ?- "." fortran-mode-syntax-table) | |
250 (modify-syntax-entry ?= "." fortran-mode-syntax-table) | |
251 (modify-syntax-entry ?* "." fortran-mode-syntax-table) | |
252 (modify-syntax-entry ?/ "." fortran-mode-syntax-table) | |
253 (modify-syntax-entry ?\' "\"" fortran-mode-syntax-table) | |
254 (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table) | |
255 (modify-syntax-entry ?\\ "/" fortran-mode-syntax-table) | |
256 (modify-syntax-entry ?. "w" fortran-mode-syntax-table) | |
1548 | 257 (modify-syntax-entry ?_ "w" fortran-mode-syntax-table) |
332 | 258 (modify-syntax-entry ?\n ">" fortran-mode-syntax-table)) |
259 | |
260 (defvar fortran-mode-map () | |
1548 | 261 "Keymap used in Fortran mode.") |
332 | 262 (if fortran-mode-map |
263 () | |
264 (setq fortran-mode-map (make-sparse-keymap)) | |
265 (define-key fortran-mode-map ";" 'fortran-abbrev-start) | |
266 (define-key fortran-mode-map "\C-c;" 'fortran-comment-region) | |
267 (define-key fortran-mode-map "\e\C-a" 'beginning-of-fortran-subprogram) | |
268 (define-key fortran-mode-map "\e\C-e" 'end-of-fortran-subprogram) | |
269 (define-key fortran-mode-map "\e;" 'fortran-indent-comment) | |
270 (define-key fortran-mode-map "\e\C-h" 'mark-fortran-subprogram) | |
271 (define-key fortran-mode-map "\e\n" 'fortran-split-line) | |
272 (define-key fortran-mode-map "\n" 'fortran-reindent-then-newline-and-indent) | |
273 (define-key fortran-mode-map "\e\C-q" 'fortran-indent-subprogram) | |
274 (define-key fortran-mode-map "\C-c\C-w" 'fortran-window-create-momentarily) | |
275 (define-key fortran-mode-map "\C-c\C-r" 'fortran-column-ruler) | |
276 (define-key fortran-mode-map "\C-c\C-p" 'fortran-previous-statement) | |
277 (define-key fortran-mode-map "\C-c\C-n" 'fortran-next-statement) | |
278 (define-key fortran-mode-map "\t" 'fortran-indent-line) | |
279 (define-key fortran-mode-map "0" 'fortran-electric-line-number) | |
280 (define-key fortran-mode-map "1" 'fortran-electric-line-number) | |
281 (define-key fortran-mode-map "2" 'fortran-electric-line-number) | |
282 (define-key fortran-mode-map "3" 'fortran-electric-line-number) | |
283 (define-key fortran-mode-map "4" 'fortran-electric-line-number) | |
284 (define-key fortran-mode-map "5" 'fortran-electric-line-number) | |
285 (define-key fortran-mode-map "6" 'fortran-electric-line-number) | |
286 (define-key fortran-mode-map "7" 'fortran-electric-line-number) | |
287 (define-key fortran-mode-map "8" 'fortran-electric-line-number) | |
288 (define-key fortran-mode-map "9" 'fortran-electric-line-number)) | |
289 | |
290 (defvar fortran-mode-abbrev-table nil) | |
291 (if fortran-mode-abbrev-table | |
292 () | |
293 (let ((ac abbrevs-changed)) | |
294 (define-abbrev-table 'fortran-mode-abbrev-table ()) | |
295 (define-abbrev fortran-mode-abbrev-table ";au" "automatic" nil) | |
296 (define-abbrev fortran-mode-abbrev-table ";b" "byte" nil) | |
1548 | 297 (define-abbrev fortran-mode-abbrev-table ";bd" "block data" nil) |
332 | 298 (define-abbrev fortran-mode-abbrev-table ";ch" "character" nil) |
299 (define-abbrev fortran-mode-abbrev-table ";cl" "close" nil) | |
300 (define-abbrev fortran-mode-abbrev-table ";c" "continue" nil) | |
301 (define-abbrev fortran-mode-abbrev-table ";cm" "common" nil) | |
302 (define-abbrev fortran-mode-abbrev-table ";cx" "complex" nil) | |
303 (define-abbrev fortran-mode-abbrev-table ";df" "define" nil) | |
304 (define-abbrev fortran-mode-abbrev-table ";di" "dimension" nil) | |
305 (define-abbrev fortran-mode-abbrev-table ";do" "double" nil) | |
306 (define-abbrev fortran-mode-abbrev-table ";dc" "double complex" nil) | |
307 (define-abbrev fortran-mode-abbrev-table ";dp" "double precision" nil) | |
308 (define-abbrev fortran-mode-abbrev-table ";dw" "do while" nil) | |
309 (define-abbrev fortran-mode-abbrev-table ";e" "else" nil) | |
310 (define-abbrev fortran-mode-abbrev-table ";ed" "enddo" nil) | |
311 (define-abbrev fortran-mode-abbrev-table ";el" "elseif" nil) | |
312 (define-abbrev fortran-mode-abbrev-table ";en" "endif" nil) | |
313 (define-abbrev fortran-mode-abbrev-table ";eq" "equivalence" nil) | |
1548 | 314 (define-abbrev fortran-mode-abbrev-table ";ew" "endwhere" nil) |
332 | 315 (define-abbrev fortran-mode-abbrev-table ";ex" "external" nil) |
316 (define-abbrev fortran-mode-abbrev-table ";ey" "entry" nil) | |
317 (define-abbrev fortran-mode-abbrev-table ";f" "format" nil) | |
318 (define-abbrev fortran-mode-abbrev-table ";fa" ".false." nil) | |
319 (define-abbrev fortran-mode-abbrev-table ";fu" "function" nil) | |
320 (define-abbrev fortran-mode-abbrev-table ";g" "goto" nil) | |
321 (define-abbrev fortran-mode-abbrev-table ";im" "implicit" nil) | |
322 (define-abbrev fortran-mode-abbrev-table ";ib" "implicit byte" nil) | |
323 (define-abbrev fortran-mode-abbrev-table ";ic" "implicit complex" nil) | |
324 (define-abbrev fortran-mode-abbrev-table ";ich" "implicit character" nil) | |
325 (define-abbrev fortran-mode-abbrev-table ";ii" "implicit integer" nil) | |
326 (define-abbrev fortran-mode-abbrev-table ";il" "implicit logical" nil) | |
327 (define-abbrev fortran-mode-abbrev-table ";ir" "implicit real" nil) | |
328 (define-abbrev fortran-mode-abbrev-table ";inc" "include" nil) | |
329 (define-abbrev fortran-mode-abbrev-table ";in" "integer" nil) | |
330 (define-abbrev fortran-mode-abbrev-table ";intr" "intrinsic" nil) | |
331 (define-abbrev fortran-mode-abbrev-table ";l" "logical" nil) | |
332 (define-abbrev fortran-mode-abbrev-table ";n" "namelist" nil) | |
333 (define-abbrev fortran-mode-abbrev-table ";o" "open" nil) ; was ;op | |
334 (define-abbrev fortran-mode-abbrev-table ";pa" "parameter" nil) | |
335 (define-abbrev fortran-mode-abbrev-table ";pr" "program" nil) | |
336 (define-abbrev fortran-mode-abbrev-table ";ps" "pause" nil) | |
337 (define-abbrev fortran-mode-abbrev-table ";p" "print" nil) | |
338 (define-abbrev fortran-mode-abbrev-table ";rc" "record" nil) | |
339 (define-abbrev fortran-mode-abbrev-table ";re" "real" nil) | |
340 (define-abbrev fortran-mode-abbrev-table ";r" "read" nil) | |
341 (define-abbrev fortran-mode-abbrev-table ";rt" "return" nil) | |
342 (define-abbrev fortran-mode-abbrev-table ";rw" "rewind" nil) | |
343 (define-abbrev fortran-mode-abbrev-table ";s" "stop" nil) | |
344 (define-abbrev fortran-mode-abbrev-table ";sa" "save" nil) | |
345 (define-abbrev fortran-mode-abbrev-table ";st" "structure" nil) | |
346 (define-abbrev fortran-mode-abbrev-table ";sc" "static" nil) | |
347 (define-abbrev fortran-mode-abbrev-table ";su" "subroutine" nil) | |
348 (define-abbrev fortran-mode-abbrev-table ";tr" ".true." nil) | |
349 (define-abbrev fortran-mode-abbrev-table ";ty" "type" nil) | |
350 (define-abbrev fortran-mode-abbrev-table ";vo" "volatile" nil) | |
351 (define-abbrev fortran-mode-abbrev-table ";w" "write" nil) | |
1548 | 352 (define-abbrev fortran-mode-abbrev-table ";wh" "where" nil) |
332 | 353 (setq abbrevs-changed ac))) |
354 | |
355 ;;;###autoload | |
356 (defun fortran-mode () | |
1548 | 357 "Major mode for editing Fortran code. |
358 \\[fortran-indent-line] indents the current Fortran line correctly. | |
359 DO statements must not share a common CONTINUE. | |
332 | 360 |
1548 | 361 Type ;? or ;\\[help-command] to display a list of built-in\ |
332 | 362 abbrevs for Fortran keywords. |
363 | |
364 Key definitions: | |
365 \\{fortran-mode-map} | |
366 | |
367 Variables controlling indentation style and extra features: | |
368 | |
369 comment-start | |
370 Normally nil in Fortran mode. If you want to use comments | |
371 starting with `!', set this to the string \"!\". | |
372 fortran-do-indent | |
373 Extra indentation within do blocks. (default 3) | |
374 fortran-if-indent | |
375 Extra indentation within if blocks. (default 3) | |
1548 | 376 fortran-structure-indent |
377 Extra indentation within structure, union and map blocks. (default 3) | |
332 | 378 fortran-continuation-indent |
1548 | 379 Extra indentation applied to continuation statements. (default 5) |
332 | 380 fortran-comment-line-column |
1548 | 381 Amount of extra indentation for text within full-line comments. (default 0) |
332 | 382 fortran-comment-indent-style |
383 nil means don't change indentation of text in full-line comments, | |
1548 | 384 fixed means indent that text at `fortran-comment-line-column' beyond |
385 the value of `fortran-minimum-statement-indent', | |
386 relative means indent at `fortran-comment-line-column' beyond the | |
332 | 387 indentation for a line of code. |
388 (default 'fixed) | |
389 fortran-comment-indent-char | |
1548 | 390 Single-character string to be inserted instead of space for |
332 | 391 full-line comment indentation. (default \" \") |
392 fortran-minimum-statement-indent | |
1548 | 393 Minimum indentation for Fortran statements. (default 6) |
332 | 394 fortran-line-number-indent |
395 Maximum indentation for line numbers. A line number will get | |
396 less than this much indentation if necessary to avoid reaching | |
397 column 5. (default 1) | |
398 fortran-check-all-num-for-matching-do | |
1548 | 399 Non-nil causes all numbered lines to be treated as possible \"continue\" |
332 | 400 statements. (default nil) |
401 fortran-blink-matching-if | |
1548 | 402 From a Fortran ENDIF statement, blink the matching IF statement. |
332 | 403 (default nil) |
404 fortran-continuation-string | |
405 Single-character string to be inserted in column 5 of a continuation | |
406 line. (default \"$\") | |
407 fortran-comment-region | |
408 String inserted by \\[fortran-comment-region] at start of each line in | |
409 region. (default \"c$$$\") | |
410 fortran-electric-line-number | |
411 Non-nil causes line number digits to be moved to the correct column | |
412 as typed. (default t) | |
1548 | 413 fortran-break-before-delimiters |
414 Non-nil causes `fortran-do-auto-fill' breaks lines before delimeters. | |
415 (default t) | |
332 | 416 fortran-startup-message |
417 Set to nil to inhibit message first time Fortran mode is used. | |
418 | |
1548 | 419 Turning on Fortran mode calls the value of the variable `fortran-mode-hook' |
332 | 420 with no args, if that value is non-nil." |
421 (interactive) | |
422 (kill-all-local-variables) | |
423 (if fortran-startup-message | |
1548 | 424 (message "Emacs Fortran mode %s. Bugs to %s" |
332 | 425 fortran-mode-version bug-fortran-mode)) |
426 (setq fortran-startup-message nil) | |
427 (setq local-abbrev-table fortran-mode-abbrev-table) | |
428 (set-syntax-table fortran-mode-syntax-table) | |
1548 | 429 (make-local-variable 'fortran-break-before-delimiters) |
430 (setq fortran-break-before-delimiters t) | |
332 | 431 (make-local-variable 'indent-line-function) |
432 (setq indent-line-function 'fortran-indent-line) | |
433 (make-local-variable 'comment-indent-hook) | |
434 (setq comment-indent-hook 'fortran-comment-hook) | |
435 (make-local-variable 'comment-line-start-skip) | |
436 (setq comment-line-start-skip | |
1548 | 437 "^[Cc*]\\(\\([^ \t\n]\\)\\2\\2*\\)?[ \t]*\\|^#.*") |
332 | 438 (make-local-variable 'comment-line-start) |
439 (setq comment-line-start "c") | |
440 (make-local-variable 'comment-start-skip) | |
441 (setq comment-start-skip "![ \t]*") | |
442 (make-local-variable 'comment-start) | |
443 (setq comment-start nil) | |
444 (make-local-variable 'require-final-newline) | |
445 (setq require-final-newline t) | |
446 (make-local-variable 'abbrev-all-caps) | |
447 (setq abbrev-all-caps t) | |
448 (make-local-variable 'indent-tabs-mode) | |
449 (setq indent-tabs-mode nil) | |
450 (setq abbrev-mode t) ; ?? (abbrev-mode 1) instead?? | |
1548 | 451 (setq fill-column 72) ; Already local? |
332 | 452 (use-local-map fortran-mode-map) |
453 (setq mode-name "Fortran") | |
454 (setq major-mode 'fortran-mode) | |
455 (make-local-variable 'fortran-tab-mode) | |
456 (make-local-variable 'fortran-comment-line-column) | |
457 (make-local-variable 'fortran-minimum-statement-indent) | |
458 (make-local-variable 'fortran-column-ruler) | |
459 (make-local-variable 'fortran-tab-mode-string) | |
460 (fortran-tab-mode (fortran-analyze-file-format)) | |
461 (run-hooks 'fortran-mode-hook)) | |
462 | |
463 (defun fortran-comment-hook () | |
464 (save-excursion | |
465 (skip-chars-backward " \t") | |
466 (max (+ 1 (current-column)) | |
467 comment-column))) | |
468 | |
469 (defun fortran-indent-comment () | |
470 "Align or create comment on current line. | |
471 Existing comments of all types are recognized and aligned. | |
472 If the line has no comment, a side-by-side comment is inserted and aligned | |
473 if the value of comment-start is not nil. | |
474 Otherwise, a separate-line comment is inserted, on this line | |
475 or on a new line inserted before this line if this line is not blank." | |
476 (interactive) | |
477 (beginning-of-line) | |
478 ;; Recognize existing comments of either kind. | |
479 (cond ((looking-at comment-line-start-skip) | |
480 (fortran-indent-line)) | |
1548 | 481 ((find-comment-start-skip) ; this catches any inline comment and |
482 ; leaves point after comment-start-skip | |
483 (if comment-start-skip | |
484 (progn (goto-char (match-beginning 0)) | |
485 (if (not (= (current-column) (fortran-comment-hook))) | |
486 (progn (delete-horizontal-space) | |
487 (indent-to (fortran-comment-hook))))) | |
488 (end-of-line))) ; otherwise goto end of line or sth else? | |
332 | 489 ;; No existing comment. |
490 ;; If side-by-side comments are defined, insert one, | |
491 ;; unless line is now blank. | |
492 ((and comment-start (not (looking-at "^[ \t]*$"))) | |
493 (end-of-line) | |
494 (delete-horizontal-space) | |
495 (indent-to (fortran-comment-hook)) | |
496 (insert comment-start)) | |
497 ;; Else insert separate-line comment, making a new line if nec. | |
498 (t | |
499 (if (looking-at "^[ \t]*$") | |
500 (delete-horizontal-space) | |
501 (beginning-of-line) | |
502 (insert "\n") | |
503 (forward-char -1)) | |
504 (insert comment-line-start) | |
505 (insert-char (if (stringp fortran-comment-indent-char) | |
506 (aref fortran-comment-indent-char 0) | |
1548 | 507 fortran-comment-indent-char) |
332 | 508 (- (calculate-fortran-indent) (current-column)))))) |
509 | |
510 (defun fortran-comment-region (beg-region end-region arg) | |
511 "Comments every line in the region. | |
512 Puts fortran-comment-region at the beginning of every line in the region. | |
513 BEG-REGION and END-REGION are args which specify the region boundaries. | |
514 With non-nil ARG, uncomments the region." | |
515 (interactive "*r\nP") | |
516 (let ((end-region-mark (make-marker)) (save-point (point-marker))) | |
517 (set-marker end-region-mark end-region) | |
518 (goto-char beg-region) | |
519 (beginning-of-line) | |
520 (if (not arg) ;comment the region | |
521 (progn (insert fortran-comment-region) | |
522 (while (and (= (forward-line 1) 0) | |
523 (< (point) end-region-mark)) | |
524 (insert fortran-comment-region))) | |
525 (let ((com (regexp-quote fortran-comment-region))) ;uncomment the region | |
526 (if (looking-at com) | |
527 (delete-region (point) (match-end 0))) | |
528 (while (and (= (forward-line 1) 0) | |
529 (< (point) end-region-mark)) | |
530 (if (looking-at com) | |
531 (delete-region (point) (match-end 0)))))) | |
532 (goto-char save-point) | |
533 (set-marker end-region-mark nil) | |
534 (set-marker save-point nil))) | |
535 | |
536 (defun fortran-abbrev-start () | |
1548 | 537 "Typing ;\\[help-command] or ;? lists all the Fortran abbrevs. |
332 | 538 Any other key combination is executed normally." |
539 (interactive) | |
540 (let (c) | |
541 (insert last-command-char) | |
542 (if (or (= (setq c (read-char)) ??) ;insert char if not equal to `?' | |
543 (= c help-char)) | |
544 (fortran-abbrev-help) | |
545 (setq unread-command-char c)))) | |
546 | |
547 (defun fortran-abbrev-help () | |
548 "List the currently defined abbrevs in Fortran mode." | |
549 (interactive) | |
550 (message "Listing abbrev table...") | |
551 (require 'abbrevlist) | |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
552 (display-buffer (fortran-prepare-abbrev-list-buffer)) |
332 | 553 (message "Listing abbrev table...done")) |
554 | |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
555 (defun fortran-prepare-abbrev-list-buffer () |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
556 (save-excursion |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
557 (set-buffer (get-buffer-create "*Abbrevs*")) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
558 (erase-buffer) |
1548 | 559 (insert-abbrev-table-description fortran-mode-abbrev-table t) |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
560 (goto-char (point-min)) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
561 (set-buffer-modified-p nil) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
562 (edit-abbrevs-mode)) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
563 (get-buffer-create "*Abbrevs*")) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
564 |
332 | 565 (defun fortran-column-ruler () |
566 "Inserts a column ruler momentarily above current line, till next keystroke. | |
1475 | 567 The ruler is defined by the value of `fortran-column-ruler'. |
332 | 568 The key typed is executed unless it is SPC." |
569 (interactive) | |
570 (momentary-string-display | |
1548 | 571 fortran-column-ruler (save-excursion |
572 (beginning-of-line) | |
573 (if (eq (window-start (selected-window)) | |
574 (window-point (selected-window))) | |
575 (progn (forward-line) (point)) | |
576 (point))) | |
332 | 577 nil "Type SPC or any command to erase ruler.")) |
578 | |
579 (defun fortran-window-create () | |
580 "Makes the window 72 columns wide. | |
1475 | 581 See also `fortran-window-create-momentarily'." |
332 | 582 (interactive) |
583 (condition-case error | |
584 (progn | |
585 (let ((window-min-width 2)) | |
1488
3d8dfdaee443
(fortran-window-create): Use screen-width, not frame-width.
Richard M. Stallman <rms@gnu.org>
parents:
1487
diff
changeset
|
586 (if (< (window-width) (screen-width)) |
3d8dfdaee443
(fortran-window-create): Use screen-width, not frame-width.
Richard M. Stallman <rms@gnu.org>
parents:
1487
diff
changeset
|
587 (enlarge-window-horizontally (- (screen-width) |
332 | 588 (window-width) 1))) |
589 (split-window-horizontally 73) | |
590 (other-window 1) | |
591 (switch-to-buffer " fortran-window-extra" t) | |
592 (select-window (previous-window)))) | |
1548 | 593 (error (message "No room for Fortran window.") |
332 | 594 'error))) |
595 | |
596 (defun fortran-window-create-momentarily (&optional arg) | |
597 "Momentarily makes the window 72 columns wide. | |
598 Optional ARG non-nil and non-unity disables the momentary feature. | |
1475 | 599 See also `fortran-window-create'." |
332 | 600 (interactive "p") |
601 (if (or (not arg) | |
602 (= arg 1)) | |
603 (save-window-excursion | |
604 (if (not (equal (fortran-window-create) 'error)) | |
605 (progn (message "Type SPC to continue editing.") | |
606 (let ((char (read-char))) | |
607 (or (equal char (string-to-char " ")) | |
608 (setq unread-command-char char)))))) | |
609 (fortran-window-create))) | |
610 | |
611 (defun fortran-split-line () | |
612 "Break line at point and insert continuation marker and alignment." | |
613 (interactive) | |
614 (delete-horizontal-space) | |
615 (if (save-excursion (beginning-of-line) (looking-at comment-line-start-skip)) | |
616 (insert "\n" comment-line-start " ") | |
617 (if fortran-tab-mode | |
618 (progn | |
619 (insert "\n\t") | |
620 (insert-char (fortran-numerical-continuation-char) 1)) | |
1548 | 621 (insert "\n " fortran-continuation-string)));Space after \n important |
622 (fortran-indent-line)) ;when the cont string is C, c or *. | |
332 | 623 |
624 (defun fortran-numerical-continuation-char () | |
625 "Return a digit for tab-digit style of continution lines. | |
626 If, previous line is a tab-digit continuation line, returns that digit | |
627 plus one. Otherwise return 1. Zero not allowed." | |
628 (save-excursion | |
629 (forward-line -1) | |
630 (if (looking-at "\t[1-9]") | |
631 (+ ?1 (% (- (char-after (+ (point) 1)) ?0) 9)) | |
632 ?1))) | |
633 | |
634 (defun delete-horizontal-regexp (chars) | |
635 "Delete all characters in CHARS around point. | |
636 CHARS is like the inside of a [...] in a regular expression | |
637 except that ] is never special and \ quotes ^, - or \." | |
638 (interactive "*s") | |
639 (skip-chars-backward chars) | |
640 (delete-region (point) (progn (skip-chars-forward chars) (point)))) | |
641 | |
642 (defun fortran-electric-line-number (arg) | |
643 "Self insert, but if part of a Fortran line number indent it automatically. | |
644 Auto-indent does not happen if a numeric arg is used." | |
645 (interactive "P") | |
646 (if (or arg (not fortran-electric-line-number)) | |
647 (if arg | |
1548 | 648 (self-insert-command (prefix-numeric-value arg)) |
332 | 649 (self-insert-command 1)) |
650 (if (or (and (= 5 (current-column)) | |
651 (save-excursion | |
652 (beginning-of-line) | |
653 (looking-at " ")));In col 5 with only spaces to left. | |
654 (and (= fortran-minimum-statement-indent (current-column)) | |
655 (save-excursion | |
656 (beginning-of-line) | |
657 (looking-at "\t"));In col 8 with a single tab to the left. | |
658 (not (or (eq last-command 'fortran-indent-line) | |
659 (eq last-command | |
660 'fortran-reindent-then-newline-and-indent)))) | |
661 (save-excursion | |
662 (re-search-backward "[^ \t0-9]" | |
663 (save-excursion | |
664 (beginning-of-line) | |
665 (point)) | |
666 t)) ;not a line number | |
667 (looking-at "[0-9]") ;within a line number | |
668 ) | |
1548 | 669 (self-insert-command (prefix-numeric-value arg)) |
332 | 670 (skip-chars-backward " \t") |
671 (insert last-command-char) | |
672 (fortran-indent-line)))) | |
673 | |
674 (defun beginning-of-fortran-subprogram () | |
1548 | 675 "Moves point to the beginning of the current Fortran subprogram." |
332 | 676 (interactive) |
677 (let ((case-fold-search t)) | |
678 (beginning-of-line -1) | |
679 (re-search-backward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move) | |
680 (if (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]") | |
681 (forward-line 1)))) | |
682 | |
683 (defun end-of-fortran-subprogram () | |
1548 | 684 "Moves point to the end of the current Fortran subprogram." |
332 | 685 (interactive) |
686 (let ((case-fold-search t)) | |
687 (beginning-of-line 2) | |
688 (re-search-forward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move) | |
689 (goto-char (match-beginning 0)) | |
690 (forward-line 1))) | |
691 | |
692 (defun mark-fortran-subprogram () | |
1548 | 693 "Put mark at end of Fortran subprogram, point at beginning. |
332 | 694 The marks are pushed." |
695 (interactive) | |
696 (end-of-fortran-subprogram) | |
697 (push-mark (point)) | |
698 (beginning-of-fortran-subprogram)) | |
1548 | 699 |
332 | 700 (defun fortran-previous-statement () |
1548 | 701 "Moves point to beginning of the previous Fortran statement. |
702 Returns `first-statement' if that statement is the first | |
332 | 703 non-comment Fortran statement in the file, and nil otherwise." |
704 (interactive) | |
705 (let (not-first-statement continue-test) | |
706 (beginning-of-line) | |
707 (setq continue-test | |
1548 | 708 (and |
709 (not (looking-at comment-line-start-skip)) | |
710 (or (looking-at | |
332 | 711 (concat "[ \t]*" (regexp-quote fortran-continuation-string))) |
1548 | 712 (or (looking-at " [^ 0\n]") |
713 (looking-at "\t[1-9]"))))) | |
332 | 714 (while (and (setq not-first-statement (= (forward-line -1) 0)) |
715 (or (looking-at comment-line-start-skip) | |
716 (looking-at "[ \t]*$") | |
717 (looking-at " [^ 0\n]") | |
718 (looking-at "\t[1-9]") | |
719 (looking-at (concat "[ \t]*" comment-start-skip))))) | |
720 (cond ((and continue-test | |
721 (not not-first-statement)) | |
722 (message "Incomplete continuation statement.")) | |
723 (continue-test | |
724 (fortran-previous-statement)) | |
725 ((not not-first-statement) | |
726 'first-statement)))) | |
727 | |
728 (defun fortran-next-statement () | |
1548 | 729 "Moves point to beginning of the next Fortran statement. |
332 | 730 Returns `last-statement' if that statement is the last |
731 non-comment Fortran statement in the file, and nil otherwise." | |
732 (interactive) | |
733 (let (not-last-statement) | |
734 (beginning-of-line) | |
1548 | 735 (while (and (setq not-last-statement |
736 (and (= (forward-line 1) 0) | |
737 (not (eobp)))) | |
332 | 738 (or (looking-at comment-line-start-skip) |
739 (looking-at "[ \t]*$") | |
740 (looking-at " [^ 0\n]") | |
741 (looking-at "\t[1-9]") | |
742 (looking-at (concat "[ \t]*" comment-start-skip))))) | |
743 (if (not not-last-statement) | |
744 'last-statement))) | |
745 | |
746 (defun fortran-blink-matching-if () | |
1548 | 747 "From a Fortran ENDIF statement, blink the matching IF statement." |
332 | 748 (let ((count 1) (top-of-window (window-start)) matching-if |
749 (endif-point (point)) message) | |
750 (if (save-excursion (beginning-of-line) | |
751 (skip-chars-forward " \t0-9") | |
752 (looking-at "end[ \t]*if\\b")) | |
753 (progn | |
754 (save-excursion | |
755 (while (and (not (= count 0)) | |
756 (not (eq (fortran-previous-statement) | |
757 'first-statement)) | |
758 (not (looking-at | |
759 "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) | |
760 ; Keep local to subprogram | |
761 (skip-chars-forward " \t0-9") | |
762 (cond ((looking-at "if[ \t]*(") | |
1548 | 763 (save-excursion |
764 (if (or | |
765 (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") | |
766 (let (then-test);multi-line if-then | |
767 (while | |
768 (and (= (forward-line 1) 0) | |
332 | 769 ;search forward for then |
1548 | 770 (or (looking-at " [^ 0\n]") |
771 (looking-at "\t[1-9]")) | |
772 (not | |
773 (setq | |
774 then-test | |
775 (looking-at | |
776 ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) | |
777 then-test)) | |
778 (setq count (- count 1))))) | |
332 | 779 ((looking-at "end[ \t]*if\\b") |
780 (setq count (+ count 1))))) | |
781 (if (not (= count 0)) | |
782 (setq message "No matching if.") | |
783 (if (< (point) top-of-window) | |
784 (setq message (concat "Matches " (buffer-substring | |
785 (progn (beginning-of-line) | |
786 (point)) | |
787 (progn (end-of-line) | |
788 (point))))) | |
789 (setq matching-if (point))))) | |
790 (if message | |
1548 | 791 (message "%s" message) |
332 | 792 (goto-char matching-if) |
793 (sit-for 1) | |
794 (goto-char endif-point)))))) | |
795 | |
796 (defun fortran-indent-line () | |
1548 | 797 "Indents current Fortran line based on its contents and on previous lines." |
332 | 798 (interactive) |
799 (let ((cfi (calculate-fortran-indent))) | |
800 (save-excursion | |
801 (beginning-of-line) | |
802 (if (or (not (= cfi (fortran-current-line-indentation))) | |
803 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t) | |
804 (not (fortran-line-number-indented-correctly-p)))) | |
805 (fortran-indent-to-column cfi) | |
806 (beginning-of-line) | |
807 (if (and (not (looking-at comment-line-start-skip)) | |
1548 | 808 (find-comment-start-skip)) |
332 | 809 (fortran-indent-comment)))) |
810 ;; Never leave point in left margin. | |
811 (if (< (current-column) cfi) | |
812 (move-to-column cfi)) | |
1548 | 813 (if (and auto-fill-hook |
814 (> (save-excursion (end-of-line) (current-column)) fill-column)) | |
815 (save-excursion | |
816 (end-of-line) | |
817 (fortran-do-auto-fill))) | |
332 | 818 (if fortran-blink-matching-if |
819 (fortran-blink-matching-if)))) | |
820 | |
821 (defun fortran-reindent-then-newline-and-indent () | |
1548 | 822 "Reindent the current Fortran line, insert a newline and indent the newline. |
823 An abbrev before point is expanded if `abbrev-mode' is non-nil." | |
332 | 824 (interactive) |
825 (if abbrev-mode (expand-abbrev)) | |
826 (save-excursion | |
827 (beginning-of-line) | |
828 (skip-chars-forward " \t") | |
829 (if (or (looking-at "[0-9]") ;Reindent only where it is most | |
830 (looking-at "end") ;likely to be necessary | |
831 (looking-at "else") | |
832 (looking-at (regexp-quote fortran-continuation-string))) | |
833 (fortran-indent-line))) | |
1548 | 834 (newline) |
332 | 835 (fortran-indent-line)) |
1548 | 836 |
332 | 837 (defun fortran-indent-subprogram () |
838 "Properly indents the Fortran subprogram which contains point." | |
839 (interactive) | |
840 (save-excursion | |
841 (mark-fortran-subprogram) | |
842 (message "Indenting subprogram...") | |
843 (indent-region (point) (mark) nil)) | |
844 (message "Indenting subprogram...done.")) | |
845 | |
846 (defun calculate-fortran-indent () | |
1548 | 847 "Calculates the Fortran indent column based on previous lines." |
332 | 848 (let (icol first-statement (case-fold-search t) |
849 (fortran-minimum-statement-indent | |
850 fortran-minimum-statement-indent)) | |
851 (save-excursion | |
852 (setq first-statement (fortran-previous-statement)) | |
853 (if first-statement | |
854 (setq icol fortran-minimum-statement-indent) | |
855 (progn | |
856 (if (= (point) (point-min)) | |
857 (setq icol fortran-minimum-statement-indent) | |
858 (setq icol (fortran-current-line-indentation))) | |
859 (skip-chars-forward " \t0-9") | |
860 (cond ((looking-at "if[ \t]*(") | |
1548 | 861 (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]") |
332 | 862 (let (then-test) ;multi-line if-then |
863 (while (and (= (forward-line 1) 0) | |
1548 | 864 ;;search forward for then |
332 | 865 (or (looking-at " [^ 0\n]") |
866 (looking-at "\t[1-9]")) | |
867 (not (setq then-test (looking-at | |
1548 | 868 ".*then\\b[ \t]\ |
869 *[^ \t_$(=a-z0-9]"))))) | |
332 | 870 then-test)) |
871 (setq icol (+ icol fortran-if-indent)))) | |
872 ((looking-at "\\(else\\|elseif\\)\\b") | |
873 (setq icol (+ icol fortran-if-indent))) | |
1548 | 874 ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b") |
875 (setq icol (+ icol fortran-if-indent))) | |
876 ((looking-at "where.*(.*)[ \t]*\n") | |
877 (setq icol (+ icol fortran-if-indent))) | |
332 | 878 ((looking-at "do\\b") |
879 (setq icol (+ icol fortran-do-indent))) | |
1548 | 880 ((looking-at |
881 "\\(structure\\|union\\|map\\)\\b[ \t]*[^ \t=(a-z]") | |
882 (setq icol (+ icol fortran-structure-indent))) | |
332 | 883 ((looking-at "end\\b[ \t]*[^ \t=(a-z]") |
1548 | 884 ;; Previous END resets indent to minimum |
332 | 885 (setq icol fortran-minimum-statement-indent)))))) |
886 (save-excursion | |
887 (beginning-of-line) | |
888 (cond ((looking-at "[ \t]*$")) | |
889 ((looking-at comment-line-start-skip) | |
890 (cond ((eq fortran-comment-indent-style 'relative) | |
891 (setq icol (+ icol fortran-comment-line-column))) | |
892 ((eq fortran-comment-indent-style 'fixed) | |
1548 | 893 (setq icol (+ fortran-minimum-statement-indent |
894 fortran-comment-line-column)))) | |
895 (setq fortran-minimum-statement-indent 0)) | |
332 | 896 ((or (looking-at (concat "[ \t]*" |
1548 | 897 (regexp-quote |
898 fortran-continuation-string))) | |
332 | 899 (looking-at " [^ 0\n]") |
900 (looking-at "\t[1-9]")) | |
901 (setq icol (+ icol fortran-continuation-indent))) | |
902 (first-statement) | |
903 ((and fortran-check-all-num-for-matching-do | |
904 (looking-at "[ \t]*[0-9]+") | |
905 (fortran-check-for-matching-do)) | |
906 (setq icol (- icol fortran-do-indent))) | |
907 (t | |
908 (skip-chars-forward " \t0-9") | |
909 (cond ((looking-at "end[ \t]*if\\b") | |
910 (setq icol (- icol fortran-if-indent))) | |
911 ((looking-at "\\(else\\|elseif\\)\\b") | |
912 (setq icol (- icol fortran-if-indent))) | |
1548 | 913 ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b") |
914 (setq icol (- icol fortran-if-indent))) | |
915 ((looking-at "end[ \t]*where\\b") | |
916 (setq icol (- icol fortran-if-indent))) | |
332 | 917 ((and (looking-at "continue\\b") |
918 (fortran-check-for-matching-do)) | |
919 (setq icol (- icol fortran-do-indent))) | |
920 ((looking-at "end[ \t]*do\\b") | |
921 (setq icol (- icol fortran-do-indent))) | |
1548 | 922 ((looking-at |
923 "end[ \t]*\ | |
924 \\(structure\\|union\\|map\\)\\b[ \t]*[^ \t=(a-z]") | |
925 (setq icol (- icol fortran-structure-indent))) | |
332 | 926 ((and (looking-at "end\\b[ \t]*[^ \t=(a-z]") |
927 (not (= icol fortran-minimum-statement-indent))) | |
928 (message "Warning: `end' not in column %d. Probably\ | |
929 an unclosed block." fortran-minimum-statement-indent)))))) | |
930 (max fortran-minimum-statement-indent icol))) | |
931 | |
932 (defun fortran-current-line-indentation () | |
933 "Indentation of current line, ignoring Fortran line number or continuation. | |
934 This is the column position of the first non-whitespace character | |
935 aside from the line number and/or column 5/8 line-continuation character. | |
936 For comment lines, returns indentation of the first | |
937 non-indentation text within the comment." | |
938 (save-excursion | |
939 (beginning-of-line) | |
940 (cond ((looking-at comment-line-start-skip) | |
941 (goto-char (match-end 0)) | |
942 (skip-chars-forward | |
1548 | 943 (if (stringp fortran-comment-indent-char) |
944 fortran-comment-indent-char | |
945 (char-to-string fortran-comment-indent-char)))) | |
332 | 946 ((or (looking-at " [^ 0\n]") |
1548 | 947 (looking-at "\t[1-9]")) |
332 | 948 (goto-char (match-end 0))) |
949 (t | |
950 ;; Move past line number. | |
1548 | 951 (skip-chars-forward "[ \t0-9]");From Uli |
952 )) | |
332 | 953 ;; Move past whitespace. |
954 (skip-chars-forward " \t") | |
955 (current-column))) | |
956 | |
957 (defun fortran-indent-to-column (col) | |
958 "Indents current line with spaces to column COL. | |
959 notes: 1) A non-zero/non-blank character in column 5 indicates a continuation | |
960 line, and this continuation character is retained on indentation; | |
1548 | 961 2) If `fortran-continuation-string' is the first non-whitespace |
962 character, this is a continuation line; | |
332 | 963 3) A non-continuation line which has a number as the first |
964 non-whitespace character is a numbered line. | |
1548 | 965 4) A TAB followed by a digit indicates a continuation line." |
332 | 966 (save-excursion |
967 (beginning-of-line) | |
968 (if (looking-at comment-line-start-skip) | |
969 (if fortran-comment-indent-style | |
970 (let ((char (if (stringp fortran-comment-indent-char) | |
971 (aref fortran-comment-indent-char 0) | |
1548 | 972 fortran-comment-indent-char))) |
332 | 973 (goto-char (match-end 0)) |
974 (delete-horizontal-regexp (concat " \t" (char-to-string char))) | |
975 (insert-char char (- col (current-column))))) | |
976 (if (looking-at "\t[1-9]") | |
977 (if fortran-tab-mode | |
978 (goto-char (match-end 0)) | |
979 (delete-char 2) | |
980 (insert " ") | |
981 (insert fortran-continuation-string)) | |
982 (if (looking-at " [^ 0\n]") | |
983 (if fortran-tab-mode | |
984 (progn (delete-char 6) | |
985 (insert "\t") | |
986 (insert-char (fortran-numerical-continuation-char) 1)) | |
987 (forward-char 6)) | |
988 (delete-horizontal-space) | |
1548 | 989 ;; Put line number in columns 0-4 |
990 ;; or put continuation character in column 5. | |
332 | 991 (cond ((eobp)) |
992 ((looking-at (regexp-quote fortran-continuation-string)) | |
993 (if fortran-tab-mode | |
994 (progn | |
995 (indent-to fortran-minimum-statement-indent) | |
996 (delete-char 1) | |
997 (insert-char (fortran-numerical-continuation-char) 1)) | |
1548 | 998 (indent-to 5) |
999 (forward-char 1))) | |
332 | 1000 ((looking-at "[0-9]+") |
1001 (let ((extra-space (- 5 (- (match-end 0) (point))))) | |
1002 (if (< extra-space 0) | |
1003 (message "Warning: line number exceeds 5-digit limit.") | |
1004 (indent-to (min fortran-line-number-indent extra-space)))) | |
1005 (skip-chars-forward "0-9"))))) | |
1006 ;; Point is now after any continuation character or line number. | |
1007 ;; Put body of statement where specified. | |
1008 (delete-horizontal-space) | |
1009 (indent-to col) | |
1010 ;; Indent any comment following code on the same line. | |
1011 (if (and comment-start-skip | |
1548 | 1012 (find-comment-start-skip)) |
332 | 1013 (progn (goto-char (match-beginning 0)) |
1014 (if (not (= (current-column) (fortran-comment-hook))) | |
1015 (progn (delete-horizontal-space) | |
1016 (indent-to (fortran-comment-hook))))))))) | |
1017 | |
1018 (defun fortran-line-number-indented-correctly-p () | |
1019 "Return t if current line's line number is correctly indented. | |
1020 Do not call if there is no line number." | |
1021 (save-excursion | |
1022 (beginning-of-line) | |
1023 (skip-chars-forward " \t") | |
1024 (and (<= (current-column) fortran-line-number-indent) | |
1025 (or (= (current-column) fortran-line-number-indent) | |
1026 (progn (skip-chars-forward "0-9") | |
1027 (= (current-column) 5)))))) | |
1028 | |
1029 (defun fortran-check-for-matching-do () | |
1548 | 1030 "When called from a numbered statement, returns t if matching DO is found. |
332 | 1031 Otherwise return a nil." |
1032 (let (charnum | |
1033 (case-fold-search t)) | |
1034 (save-excursion | |
1035 (beginning-of-line) | |
1036 (if (looking-at "[ \t]*[0-9]+") | |
1037 (progn | |
1038 (skip-chars-forward " \t") | |
1039 (skip-chars-forward "0") ;skip past leading zeros | |
1040 (setq charnum (buffer-substring (point) | |
1041 (progn (skip-chars-forward "0-9") | |
1042 (point)))) | |
1043 (beginning-of-line) | |
1044 (and (re-search-backward | |
1045 (concat | |
1548 | 1046 "\\(^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]\\)\\|\\(^[ \t0-9]*do\ |
1047 [ \t]*0*" | |
1048 charnum "\\b\\)\\|\\(^[ \t]*0*" charnum "\\b\\)") | |
332 | 1049 nil t) |
1050 (looking-at (concat "^[ \t0-9]*do[ \t]*0*" charnum)))))))) | |
1051 | |
1052 (defun fortran-analyze-file-format () | |
1053 "Return 0 if Fixed format is used, 1 if Tab formatting is used. | |
1475 | 1054 Use `fortran-tab-mode-default' if no non-comment statements are found in the |
1055 file before the end or the first `fortran-analyze-depth' lines." | |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1056 (let ((i 0)) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1057 (save-excursion |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1058 (goto-char (point-min)) |
1548 | 1059 (setq i 0) |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1060 (while (not (or |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1061 (eobp) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1062 (looking-at "\t") |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1063 (looking-at " ") |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1064 (> i fortran-analyze-depth))) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1065 (forward-line) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1066 (setq i (1+ i))) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1067 (cond |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1068 ((looking-at "\t") 1) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1069 ((looking-at " ") 0) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1070 (fortran-tab-mode-default 1) |
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1071 (t 0))))) |
332 | 1072 |
1073 (defun fortran-tab-mode (arg) | |
1475 | 1074 "Toggle `fortran-tab-mode' which indicates style of continuation lines. |
332 | 1075 With no argument, toggle on/off the tabbing mode of continuation lines. |
1475 | 1076 If argument is a positive number, or non-nil if not a number, |
1077 `fortran-tab-mode' is turned on. Otherwise `fortran-tab-mode' is false" | |
332 | 1078 (interactive "P") |
1079 (setq fortran-tab-mode | |
1080 (if (null arg) (not fortran-tab-mode) | |
1081 (if (numberp arg) | |
1082 (> (prefix-numeric-value arg) 0) | |
1485
a6da00e1c5ad
(fortran-tab-mode): Add defvar.
Richard M. Stallman <rms@gnu.org>
parents:
1475
diff
changeset
|
1083 arg))) |
332 | 1084 (if fortran-tab-mode |
1085 (fortran-setup-tab-format-style) | |
1086 (fortran-setup-fixed-format-style)) | |
1087 (set-buffer-modified-p (buffer-modified-p))) ;No-op, but updates mode line. | |
1088 | |
1089 (defun fortran-setup-tab-format-style () | |
1548 | 1090 "Set up Fortran mode to use the TAB-digit mode of continuation lines. |
1091 Use the command `fortran-tab-mode' to toggle between this and fixed | |
1092 format style." | |
332 | 1093 (setq fortran-minimum-statement-indent (max tab-width 6)) |
1094 (setq indent-tabs-mode t) | |
1095 (setq fortran-column-ruler | |
1096 (concat | |
1548 | 1097 "0 810 20 30 40 5\ |
1098 0 60 70\n" | |
1099 "[ ]| { | | | | | | | | \ | |
1100 | | | | |}\n")) | |
332 | 1101 (setq fortran-tab-mode-string " TAB-format") |
1102 (set-buffer-modified-p (buffer-modified-p))) | |
1103 | |
1104 (defun fortran-setup-fixed-format-style () | |
1548 | 1105 "Set up Fortran mode to use the column 6 mode of continuation lines. |
1475 | 1106 Use the command `fortran-tab-mode' to toggle between this and tab |
332 | 1107 character format style." |
1108 (setq fortran-minimum-statement-indent 6) | |
1109 (setq indent-tabs-mode nil) | |
1110 (setq fortran-column-ruler | |
1111 (concat | |
1548 | 1112 "0 4 6 10 20 30 40 5\ |
1113 0 60 70\n" | |
1114 "[ ]|{ | | | | | | | | \ | |
1115 | | | | |}\n")) | |
332 | 1116 (setq fortran-tab-mode-string " Fixed-format") |
1117 (set-buffer-modified-p (buffer-modified-p))) | |
1118 | |
1548 | 1119 (or (assq 'fortran-tab-mode-string minor-mode-alist) |
332 | 1120 (setq minor-mode-alist (cons |
1121 '(fortran-tab-mode-string fortran-tab-mode-string) | |
1122 minor-mode-alist))) | |
1123 | |
1548 | 1124 (defun find-comment-start-skip () |
1125 "Move to past `comment-start-skip' found on current line. | |
1126 Return t if `comment-start-skip' found, nil if not." | |
1127 ;;; In order to move point only if comment-start-skip is found, | |
1128 ;;; this one uses a lot of save-excursions. Note that re-search-forward | |
1129 ;;; moves point even if comment-start-skip is inside a string-constant. | |
1130 ;;; Some code expects certain values for match-beginning and end | |
1131 (interactive) | |
1132 (let ((save-match-beginning) (save-match-end)) | |
1133 (if (save-excursion | |
1134 (re-search-forward comment-start-skip | |
1135 (save-excursion (end-of-line) (point)) t)) | |
1136 (progn | |
1137 (setq save-match-beginning (match-beginning 0)) | |
1138 (setq save-match-end (match-end 0)) | |
1139 (if (is-in-fortran-string-p (match-beginning 0)) | |
1140 (progn | |
1141 (save-excursion | |
1142 (goto-char save-match-end) | |
1143 (find-comment-start-skip)) ; recurse for rest of line | |
1144 ) | |
1145 (goto-char save-match-beginning) | |
1146 (re-search-forward comment-start-skip | |
1147 (save-excursion (end-of-line) (point)) t) | |
1148 (goto-char (match-end 0)) | |
1149 t)) | |
1150 nil))) | |
1151 | |
1152 (defun is-in-fortran-string-p (pos) | |
1153 "Return t if POS (a buffer position) is inside a standard Fortran string. | |
1154 Fortran strings are delimeted by apostrophes (\'). Quote-Escape-sequences | |
1155 (\\'), strings delimited by \" and detection of syntax-errors | |
1156 (unbalanced quotes) are NOT supported." | |
1157 ;;; The algorithm is simple: start at point with value nil | |
1158 ;;; and toggle value at each quote found until end of line. | |
1159 ;;; The quote skip is hard-coded, maybe it's possible to change this | |
1160 ;;; and use something like 'string-constant-delimiter' (which | |
1161 ;;; doesn't exist yet) so this function can be used by other modes, | |
1162 ;;; but then one must pay attention to escape sequences, multi-line-constants | |
1163 ;;; and such things. | |
1164 (let ((is-in-fortran-string nil)) | |
1165 (save-excursion | |
1166 (goto-char pos) | |
1167 (fortran-previous-statement) | |
1168 (fortran-next-statement) | |
1169 (while (< (point) pos) | |
1170 ;; Make sure we don't count quotes in continuation column. | |
1171 (if (looking-at "^ ") | |
1172 (goto-char (+ 1 (match-end 0))) | |
1173 (if (and (not is-in-fortran-string) | |
1174 (looking-at comment-start-skip)) | |
1175 (beginning-of-line 2) | |
1176 (if (looking-at "'") | |
1177 (setq is-in-fortran-string (not is-in-fortran-string))) | |
1178 (forward-char 1))))) | |
1179 is-in-fortran-string)) | |
1180 | |
1181 (defun fortran-auto-fill-mode (arg) | |
1182 "Toggle fortran-auto-fill mode. | |
1183 With ARG, turn `fortran-auto-fill' mode on iff ARG is positive. | |
1184 In `fortran-auto-fill' mode, inserting a space at a column beyond `fill-column' | |
1185 automatically breaks the line at a previous space." | |
1186 (interactive "P") | |
1187 (prog1 (setq auto-fill-hook | |
1188 (if (if (null arg) | |
1189 (not auto-fill-hook) | |
1190 (> (prefix-numeric-value arg) 0)) | |
1191 'fortran-indent-line | |
1192 nil)) | |
1193 ;; update mode-line | |
1194 (set-buffer-modified-p (buffer-modified-p)))) | |
1195 | |
1196 (defun fortran-do-auto-fill () | |
1197 (interactive) | |
1198 (let* ((opoint (point)) | |
1199 (bol (save-excursion (beginning-of-line) (point))) | |
1200 (eol (save-excursion (end-of-line) (point))) | |
1201 (bos (min eol (+ bol (fortran-current-line-indentation)))) | |
1202 (quote | |
1203 (save-excursion | |
1204 (goto-char bol) | |
1205 (if (looking-at comment-line-start-skip) | |
1206 nil ; OK to break quotes on comment lines. | |
1207 (move-to-column fill-column) | |
1208 (cond ((is-in-fortran-string-p (point)) | |
1209 (save-excursion (re-search-backward "[^']'[^']" bol t) | |
1210 (if fortran-break-before-delimiters | |
1211 (point) | |
1212 (1+ (point))))) | |
1213 (t nil))))) | |
1214 ;; | |
1215 ;; decide where to split the line. If a position for a quoted | |
1216 ;; string was found above then use that, else break the line | |
1217 ;; before the last delimiter. | |
1218 ;; Delimeters are whitespace, commas, and operators. | |
1219 ;; Will break before a pair of *'s. | |
1220 ;; | |
1221 (fill-point | |
1222 (or quote | |
1223 (save-excursion | |
1224 (move-to-column (1+ fill-column)) | |
1225 (skip-chars-backward "^ \t\n,'+-/*=)" | |
1226 ;;; (if fortran-break-before-delimiters | |
1227 ;;; "^ \t\n,'+-/*=" "^ \t\n,'+-/*=)") | |
1228 ) | |
1229 (if (<= (point) (1+ bos)) | |
1230 (progn | |
1231 (move-to-column (1+ fill-column)) | |
1232 (if (not (re-search-forward "[\t\n,'+-/*)=]" eol t)) | |
1233 (goto-char bol)))) | |
1234 (if (bolp) | |
1235 (re-search-forward "[ \t]" opoint t) | |
1236 (forward-char -1) | |
1237 (if (looking-at "'") | |
1238 (forward-char 1) | |
1239 (skip-chars-backward " \t\*"))) | |
1240 (if fortran-break-before-delimiters | |
1241 (point) | |
1242 (1+ (point)))))) | |
1243 ) | |
1244 ;; if we are in an in-line comment, don't break unless the | |
1245 ;; line of code is longer than it should be. Otherwise | |
1246 ;; break the line at the column computed above. | |
1247 ;; | |
1248 ;; Need to use find-comment-start-skip to make sure that quoted !'s | |
1249 ;; don't prevent a break. | |
1250 (if (not (or (save-excursion | |
1251 (if (and (re-search-backward comment-start-skip bol t) | |
1252 (not (is-in-fortran-string-p (point)))) | |
1253 (progn | |
1254 (skip-chars-backward " \t") | |
1255 (< (current-column) (1+ fill-column))))) | |
1256 (save-excursion | |
1257 (goto-char fill-point) | |
1258 (bolp)))) | |
1259 (if (> (save-excursion | |
1260 (goto-char fill-point) (current-column)) | |
1261 (1+ fill-column)) | |
1262 (progn (goto-char fill-point) | |
1263 (fortran-break-line)) | |
1264 (save-excursion | |
1265 (if (> (save-excursion | |
1266 (goto-char fill-point) | |
1267 (current-column)) | |
1268 (+ (calculate-fortran-indent) fortran-continuation-indent)) | |
1269 (progn | |
1270 (goto-char fill-point) | |
1271 (fortran-break-line)))))) | |
1272 )) | |
1273 (defun fortran-break-line () | |
1274 (let ((opoint (point)) | |
1275 (bol (save-excursion (beginning-of-line) (point))) | |
1276 (eol (save-excursion (end-of-line) (point))) | |
1277 (comment-string nil)) | |
1278 | |
1279 (save-excursion | |
1280 (if (and comment-start-skip (find-comment-start-skip)) | |
1281 (progn | |
1282 (re-search-backward comment-start-skip bol t) | |
1283 (setq comment-string (buffer-substring (point) eol)) | |
1284 (delete-region (point) eol)))) | |
1285 ;;; Forward line 1 really needs to go to next non white line | |
1286 (if (save-excursion (forward-line 1) | |
1287 (or (looking-at " [^ 0\n]") | |
1288 (looking-at "\t[1-9]"))) | |
1289 (progn | |
1290 (forward-line 1) | |
1291 (delete-indentation) | |
1292 (delete-char 2) | |
1293 (delete-horizontal-space) | |
1294 (fortran-do-auto-fill)) | |
1295 (fortran-split-line)) | |
1296 (if comment-string | |
1297 (save-excursion | |
1298 (goto-char bol) | |
1299 (end-of-line) | |
1300 (delete-horizontal-space) | |
1301 (indent-to (fortran-comment-hook)) | |
1302 (insert comment-string))))) | |
1303 | |
584 | 1304 (provide 'fortran) |
1305 | |
660
08eb386dd0f3
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
584
diff
changeset
|
1306 ;;; fortran.el ends here |