diff options
| author | Glenn Morris | 2009-08-30 01:38:09 +0000 |
|---|---|---|
| committer | Glenn Morris | 2009-08-30 01:38:09 +0000 |
| commit | 4a948dbfcf14c0ea68745b54490c3b3711f76eb3 (patch) | |
| tree | 352cc28eb1ff04a19e0d6f7fc465b6d993f6c09f | |
| parent | 486cf3b876103af5d21eb4834cfcf1fe51c94985 (diff) | |
| download | emacs-4a948dbfcf14c0ea68745b54490c3b3711f76eb3.tar.gz emacs-4a948dbfcf14c0ea68745b54490c3b3711f76eb3.zip | |
(fortran-start-prog-re): New constant, extracted from fortran-current-defun.
(fortran-beginning-of-subprogram): Be more precise about finding the
start, to avoid an infinite loop in end-of-defun. (Bug#4259)
(fortran-end-of-subprogram): Simplify.
(fortran-current-defun): Use fortran-start-prog-re.
| -rw-r--r-- | lisp/ChangeLog | 9 | ||||
| -rw-r--r-- | lisp/progmodes/fortran.el | 80 |
2 files changed, 56 insertions, 33 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0da2525f51a..840111dadfd 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2009-08-30 Glenn Morris <rgm@gnu.org> | ||
| 2 | |||
| 3 | * progmodes/fortran.el (fortran-start-prog-re): New constant, extracted | ||
| 4 | from fortran-current-defun. | ||
| 5 | (fortran-beginning-of-subprogram): Be more precise about finding the | ||
| 6 | start, to avoid an infinite loop in end-of-defun. (Bug#4259) | ||
| 7 | (fortran-end-of-subprogram): Simplify. | ||
| 8 | (fortran-current-defun): Use fortran-start-prog-re. | ||
| 9 | |||
| 1 | 2009-08-29 Juanma Barranquero <lekktu@gmail.com> | 10 | 2009-08-29 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 11 | ||
| 3 | * subr.el (do-after-load-evaluation): Simplify. | 12 | * subr.el (do-after-load-evaluation): Simplify. |
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index d729462731c..ebe6598c5b4 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | ;;; fortran.el --- Fortran mode for GNU Emacs | 1 | ;;; fortran.el --- Fortran mode for GNU Emacs |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, | 3 | ;; Copyright (C) 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, |
| 4 | ;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 4 | ;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
| 5 | ;; Free Software Foundation, Inc. | 5 | ;; Free Software Foundation, Inc. |
| 6 | 6 | ||
| 7 | ;; Author: Michael D. Prange <prange@erl.mit.edu> | 7 | ;; Author: Michael D. Prange <prange@erl.mit.edu> |
| 8 | ;; Maintainer: Glenn Morris <rgm@gnu.org> | 8 | ;; Maintainer: Glenn Morris <rgm@gnu.org> |
| @@ -330,6 +330,13 @@ characters long.") | |||
| 330 | (defconst fortran-if-start-re "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(" | 330 | (defconst fortran-if-start-re "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(" |
| 331 | "Regexp matching the start of an IF statement.") | 331 | "Regexp matching the start of an IF statement.") |
| 332 | 332 | ||
| 333 | ;; Note fortran-current-defun uses the subgroups. | ||
| 334 | (defconst fortran-start-prog-re | ||
| 335 | "^[ \t]*\\(program\\|subroutine\\|function\ | ||
| 336 | \\|[ \ta-z0-9*()]*[ \t]+function\\|\ | ||
| 337 | \\(block[ \t]*data\\)\\)" | ||
| 338 | "Regexp matching the start of a subprogram, from the line start.") | ||
| 339 | |||
| 333 | (defconst fortran-end-prog-re1 | 340 | (defconst fortran-end-prog-re1 |
| 334 | "end\ | 341 | "end\ |
| 335 | \\([ \t]*\\(program\\|subroutine\\|function\\|block[ \t]*data\\)\\>\ | 342 | \\([ \t]*\\(program\\|subroutine\\|function\\|block[ \t]*data\\)\\>\ |
| @@ -1182,37 +1189,47 @@ Auto-indent does not happen if a numeric ARG is used." | |||
| 1182 | (+ fortran-line-length | 1189 | (+ fortran-line-length |
| 1183 | (line-beginning-position))))))) | 1190 | (line-beginning-position))))))) |
| 1184 | 1191 | ||
| 1185 | ;; Note that you can't just check backwards for `subroutine' &c in | 1192 | ;; This is more complex than first expected because the beginning of a |
| 1186 | ;; case of un-marked main programs not at the start of the file. | 1193 | ;; main program may be implicit (ie not marked by a PROGRAM statement). |
| 1194 | ;; This would be fine (we could just go to bob in the absence of a match), | ||
| 1195 | ;; except it need not even be the first subprogram in the file (eg it | ||
| 1196 | ;; could follow a subroutine). Hence we have to search for END | ||
| 1197 | ;; statements instead. | ||
| 1198 | ;; cf fortran-beginning-of-block, f90-beginning-of-subprogram | ||
| 1199 | ;; Note that unlike the latter, we don't have to worry about nested | ||
| 1200 | ;; subprograms (?). | ||
| 1201 | ;; FIXME push-mark? | ||
| 1187 | (defun fortran-beginning-of-subprogram () | 1202 | (defun fortran-beginning-of-subprogram () |
| 1188 | "Move point to the beginning of the current Fortran subprogram." | 1203 | "Move point to the beginning of the current Fortran subprogram." |
| 1189 | (interactive) | 1204 | (interactive) |
| 1190 | (save-match-data | 1205 | (let ((case-fold-search t)) |
| 1191 | (let ((case-fold-search t)) | 1206 | ;; If called already at the start of subprogram, go to the previous. |
| 1192 | (beginning-of-line -1) | 1207 | (beginning-of-line (if (bolp) 0 1)) |
| 1193 | (if (catch 'ok | 1208 | (save-match-data |
| 1194 | (while (re-search-backward fortran-end-prog-re nil 'move) | 1209 | (or (looking-at fortran-start-prog-re) |
| 1195 | (if (fortran-check-end-prog-re) | 1210 | ;; This leaves us at bob if before the first subprogram. |
| 1196 | (throw 'ok t)))) | 1211 | (eq (fortran-previous-statement) 'first-statement) |
| 1197 | (forward-line))))) | 1212 | (if (or (catch 'ok |
| 1198 | 1213 | (while (re-search-backward fortran-end-prog-re nil 'move) | |
| 1214 | (if (fortran-check-end-prog-re) (throw 'ok t)))) | ||
| 1215 | ;; If the search failed, must be at bob. | ||
| 1216 | ;; First code line is the start of the subprogram. | ||
| 1217 | ;; FIXME use a more rigorous test, cf fortran-next-statement? | ||
| 1218 | ;; Though that needs to handle continuations too. | ||
| 1219 | (not (looking-at "^\\([ \t]*[0-9]\\|[ \t]+[^!#]\\)"))) | ||
| 1220 | (fortran-next-statement)))))) | ||
| 1221 | |||
| 1222 | ;; This is simpler than f-beginning-of-s because the end of a | ||
| 1223 | ;; subprogram is never implicit. | ||
| 1199 | (defun fortran-end-of-subprogram () | 1224 | (defun fortran-end-of-subprogram () |
| 1200 | "Move point to the end of the current Fortran subprogram." | 1225 | "Move point to the end of the current Fortran subprogram." |
| 1201 | (interactive) | 1226 | (interactive) |
| 1202 | (save-match-data | 1227 | (let ((case-fold-search t)) |
| 1203 | (let ((case-fold-search t)) | 1228 | (beginning-of-line) |
| 1204 | (if (save-excursion ; on END | 1229 | (save-match-data |
| 1205 | (beginning-of-line) | 1230 | (while (and (re-search-forward fortran-end-prog-re nil 'move) |
| 1206 | (and (looking-at fortran-end-prog-re) | 1231 | (not (fortran-check-end-prog-re)))) |
| 1207 | (fortran-check-end-prog-re))) | 1232 | (forward-line)))) |
| 1208 | (forward-line) | ||
| 1209 | (beginning-of-line 2) | ||
| 1210 | (when (catch 'ok | ||
| 1211 | (while (re-search-forward fortran-end-prog-re nil 'move) | ||
| 1212 | (if (fortran-check-end-prog-re) | ||
| 1213 | (throw 'ok t)))) | ||
| 1214 | (goto-char (match-beginning 0)) | ||
| 1215 | (forward-line)))))) | ||
| 1216 | 1233 | ||
| 1217 | (defun fortran-previous-statement () | 1234 | (defun fortran-previous-statement () |
| 1218 | "Move point to beginning of the previous Fortran statement. | 1235 | "Move point to beginning of the previous Fortran statement. |
| @@ -2137,19 +2154,16 @@ arg DO-SPACE prevents stripping the whitespace." | |||
| 2137 | (replace-match "" nil nil nil 1) | 2154 | (replace-match "" nil nil nil 1) |
| 2138 | (unless do-space (delete-horizontal-space))))) | 2155 | (unless do-space (delete-horizontal-space))))) |
| 2139 | 2156 | ||
| 2140 | ;; This code used to live in add-log.el, but this is a better place | 2157 | ;; This code used to live in add-log.el, but this is a better place for it. |
| 2141 | ;; for it. | ||
| 2142 | (defun fortran-current-defun () | 2158 | (defun fortran-current-defun () |
| 2143 | "Function to use for `add-log-current-defun-function' in Fortran mode." | 2159 | "Function to use for `add-log-current-defun-function' in Fortran mode." |
| 2144 | (save-excursion | 2160 | (save-excursion |
| 2145 | ;; We must be inside function body for this to work. | 2161 | ;; We must be inside function body for this to work. |
| 2146 | (fortran-beginning-of-subprogram) | 2162 | (fortran-beginning-of-subprogram) |
| 2147 | (let ((case-fold-search t)) ; case-insensitive | 2163 | (let ((case-fold-search t)) |
| 2148 | ;; Search for fortran subprogram start. | 2164 | ;; Search for fortran subprogram start. |
| 2149 | (if (re-search-forward | 2165 | (if (re-search-forward |
| 2150 | (concat "^[ \t]*\\(program\\|subroutine\\|function" | 2166 | fortran-start-prog-re |
| 2151 | "\\|[ \ta-z0-9*()]*[ \t]+function\\|" | ||
| 2152 | "\\(block[ \t]*data\\)\\)") | ||
| 2153 | (save-excursion (fortran-end-of-subprogram) | 2167 | (save-excursion (fortran-end-of-subprogram) |
| 2154 | (point)) | 2168 | (point)) |
| 2155 | t) | 2169 | t) |