aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2009-08-30 01:38:09 +0000
committerGlenn Morris2009-08-30 01:38:09 +0000
commit4a948dbfcf14c0ea68745b54490c3b3711f76eb3 (patch)
tree352cc28eb1ff04a19e0d6f7fc465b6d993f6c09f
parent486cf3b876103af5d21eb4834cfcf1fe51c94985 (diff)
downloademacs-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/ChangeLog9
-rw-r--r--lisp/progmodes/fortran.el80
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 @@
12009-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
12009-08-29 Juanma Barranquero <lekktu@gmail.com> 102009-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)