X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ac3232837188f7e1c4ffe34b76edede0ccb54f5e..58635e4de85621d4f16befe15b1df44a637bd078:/lisp/progmodes/fortran.el diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index d5b551b78e..67a214977b 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el @@ -1,8 +1,6 @@ ;;; fortran.el --- Fortran mode for GNU Emacs -;; Copyright (C) 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, -;; 2002, 2003, 2004, 2005, 2006, 2007, 2008 -;; Free Software Foundation, Inc. +;; Copyright (C) 1986, 1993-1995, 1997-2011 Free Software Foundation, Inc. ;; Author: Michael D. Prange ;; Maintainer: Glenn Morris @@ -83,8 +81,8 @@ A non-nil value specifies tab-digit style of continuation control. A value of nil specifies that continuation lines are marked with a character in column 6." :type 'boolean + :safe 'booleanp :group 'fortran-indent) -(put 'fortran-tab-mode-default 'safe-local-variable 'booleanp) ;; TODO add more detail of what tab mode is to doc string. (defcustom fortran-tab-mode-string @@ -96,34 +94,35 @@ with a character in column 6." (interactive) (describe-variable 'fortran-tab-mode-string)))) - "String to appear in mode line in TAB format buffers." + "String to appear in mode line in TAB format buffers. +See Info node `(emacs)ForIndent Cont'." :type 'string + :risky t :group 'fortran-indent) -(put 'fortran-tab-mode-string 'risky-local-variable t) (defcustom fortran-do-indent 3 "Extra indentation applied to DO blocks." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-do-indent 'safe-local-variable 'integerp) (defcustom fortran-if-indent 3 "Extra indentation applied to IF, SELECT CASE and WHERE blocks." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-if-indent 'safe-local-variable 'integerp) (defcustom fortran-structure-indent 3 "Extra indentation applied to STRUCTURE, UNION, MAP and INTERFACE blocks." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-structure-indent 'safe-local-variable 'integerp) (defcustom fortran-continuation-indent 5 "Extra indentation applied to continuation lines." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-continuation-indent 'safe-local-variable 'integerp) (defcustom fortran-comment-indent-style 'fixed "How to indent comments. @@ -134,24 +133,24 @@ nil forces comment lines not to be touched; `relative' indents to current Fortran indentation plus `fortran-comment-line-extra-indent'." :type '(radio (const :tag "Untouched" nil) (const fixed) (const relative)) + :safe (lambda (value) (memq value '(nil fixed relative))) :group 'fortran-indent) -(put 'fortran-comment-indent 'safe-local-variable - (lambda (value) (memq value '(nil fixed relative)))) (defcustom fortran-comment-line-extra-indent 0 "Amount of extra indentation for text within full-line comments." :type 'integer + :safe 'integerp :group 'fortran-indent :group 'fortran-comment) -(put 'fortran-comment-line-extra-indent 'safe-local-variable 'integerp) (defcustom fortran-comment-line-start "C" "Delimiter inserted to start new full-line comment. -You might want to change this to \"*\", for instance." +You might want to change this to \"*\", for instance; or \"!\" to +allow trailing comments on a line." :version "21.1" :type 'string + :safe 'stringp :group 'fortran-comment) -(put 'fortran-comment-line-start 'safe-local-variable 'stringp) ;; This used to match preprocessor lines too, but that messes up ;; filling and doesn't seem to be necessary. @@ -160,8 +159,8 @@ You might want to change this to \"*\", for instance." "Regexp to match the start of a full-line comment." :version "21.1" :type 'regexp + :safe 'stringp :group 'fortran-comment) -(put 'fortran-comment-line-start-skip 'safe-local-variable 'stringp) (defcustom fortran-directive-re "^[ \t]*#.*" @@ -170,20 +169,20 @@ The matching text will be fontified with `font-lock-keyword-face'. The matching line will be given zero indentation." :version "22.1" :type 'regexp + :safe 'stringp :group 'fortran-indent) -(put 'fortran-directive-re 'safe-local-variable 'stringp) (defcustom fortran-minimum-statement-indent-fixed 6 "Minimum statement indentation for fixed format continuation style." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-minimum-statement-indent-fixed 'safe-local-variable 'integerp) (defcustom fortran-minimum-statement-indent-tab (max tab-width 6) "Minimum statement indentation for TAB format continuation style." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-minimum-statement-indent-tab 'safe-local-variable 'integerp) ;; Note that this is documented in the v18 manuals as being a string ;; of length one rather than a single character. @@ -192,31 +191,29 @@ The matching line will be given zero indentation." "Single-character string inserted for Fortran comment indentation. Normally a space." :type 'string + :safe (lambda (value) (or (characterp value) + (and (stringp value) (= (length value) 1)))) :group 'fortran-comment) -(put 'fortran-comment-indent-char 'safe-local-variable - (lambda (value) (or (characterp value) - (and (stringp value) - (= (length value) 1))))) (defcustom fortran-line-number-indent 1 "Maximum indentation for Fortran line numbers. 5 means right-justify them within their five-column field." :type 'integer + :safe 'integerp :group 'fortran-indent) -(put 'fortran-line-number-indent 'safe-local-variable 'integerp) (defcustom fortran-check-all-num-for-matching-do nil "Non-nil causes all numbered lines to be treated as possible DO loop ends." :type 'boolean + :safe 'booleanp :group 'fortran) -(put 'fortran-check-all-num-for-matching-do 'safe-local-variable 'booleanp) (defcustom fortran-blink-matching-if nil "Non-nil causes \\[fortran-indent-line] on ENDIF to blink on matching IF. Also, from an ENDDO statement blink on matching DO [WHILE] statement." :type 'boolean + :safe 'booleanp :group 'fortran) -(put 'fortran-blink-matching-if 'safe-local-variable 'booleanp) (defcustom fortran-continuation-string "$" "Single-character string used for Fortran continuation lines. @@ -224,25 +221,23 @@ In fixed format continuation style, this character is inserted in column 6 by \\[fortran-split-line] to begin a continuation line. Also, if \\[fortran-indent-line] finds this at the beginning of a line, it will convert the line into a continuation line of the -appropriate style. Normally $." +appropriate style. Normally \"$\"." :type 'string + :safe (lambda (value) (and (stringp value) (= (length value) 1))) :group 'fortran) -(put 'fortran-continuation-string 'safe-local-variable - (lambda (value) (and (stringp value) - (= (length value) 1)))) (defcustom fortran-comment-region "c$$$" "String inserted by \\[fortran-comment-region] at start of each \ line in region." :type 'string + :safe 'stringp :group 'fortran-comment) -(put 'fortran-comment-region 'safe-local-variable 'stringp) (defcustom fortran-electric-line-number t "Non-nil causes line numbers to be moved to the correct column as typed." :type 'boolean + :safe 'booleanp :group 'fortran) -(put 'fortran-electric-line-number 'safe-local-variable 'booleanp) ;; TODO use fortran-line-length, somehow. (defcustom fortran-column-ruler-fixed @@ -254,8 +249,8 @@ line in region." This variable is used in fixed format mode. See the variable `fortran-column-ruler-tab' for TAB format mode." :type 'string + :safe 'stringp :group 'fortran) -(put 'fortran-column-ruler-fixed 'safe-local-variable 'stringp) ;; TODO use fortran-line-length, somehow. (defcustom fortran-column-ruler-tab @@ -267,21 +262,21 @@ See the variable `fortran-column-ruler-tab' for TAB format mode." This variable is used in TAB format mode. See the variable `fortran-column-ruler-fixed' for fixed format mode." :type 'string + :safe 'stringp :group 'fortran) -(put 'fortran-column-ruler-tab 'safe-local-variable 'stringp) (defcustom fortran-analyze-depth 100 "Number of lines to scan to identify fixed or TAB format style." :type 'integer + :safe 'integerp :group 'fortran) -(put 'fortran-analyze-depth 'safe-local-variable 'integerp) (defcustom fortran-break-before-delimiters t "Non-nil causes filling to break lines before delimiters. Delimiters are characters matching the regexp `fortran-break-delimiters-re'." :type 'boolean + :safe 'booleanp :group 'fortran) -(put 'fortran-break-before-delimiters 'safe-local-variable 'booleanp) ;; TODO 0 as no-limit, as per g77. (defcustom fortran-line-length 72 @@ -294,6 +289,7 @@ buffers and the default) or the function buffer). This corresponds to the g77 compiler option `-ffixed-line-length-N'." :type 'integer + :safe 'integerp :initialize 'custom-initialize-default :set (lambda (symbol value) ;; Do all fortran buffers, and the default. @@ -301,7 +297,6 @@ buffer). This corresponds to the g77 compiler option :version "23.1" :group 'fortran) -(put 'fortran-line-length 'safe-local-variable 'integerp) (make-variable-buffer-local 'fortran-line-length) (defcustom fortran-mode-hook nil @@ -328,6 +323,13 @@ characters long.") (defconst fortran-if-start-re "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(" "Regexp matching the start of an IF statement.") +;; Note fortran-current-defun uses the subgroups. +(defconst fortran-start-prog-re + "^[ \t]*\\(program\\|subroutine\\|function\ +\\|[ \ta-z0-9*()]*[ \t]+function\\|\ +\\(block[ \t]*data\\)\\)" + "Regexp matching the start of a subprogram, from the line start.") + (defconst fortran-end-prog-re1 "end\ \\([ \t]*\\(program\\|subroutine\\|function\\|block[ \t]*data\\)\\>\ @@ -399,6 +401,28 @@ program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?" '("^ *\\([0-9]+\\)" . font-lock-constant-face))) "Medium level highlighting for Fortran mode.") +;; See bug#1385. Never really looked into _why_ this matters... +(defun fortran-match-and-skip-declaration (limit) + "Like `font-lock-match-c-style-declaration-item-and-skip-to-next'. +The only difference is, it returns t in a case when the default returns nil." + (when (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?") + (when (and (match-end 2) (> (- (match-end 2) (match-beginning 2)) 1)) + (let ((pos (point))) + (skip-chars-backward " \t\n") + (skip-syntax-backward "w") + (unless (looking-at "\\(\\sw+\\)[ \t\n]*\\sw+[ \t\n]*\\(((?\\)?") + (goto-char pos) + (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?")))) + (save-match-data + (condition-case nil + (save-restriction + (narrow-to-region (point-min) limit) + (goto-char (match-end 1)) + (while (not (looking-at "[ \t\n]*\\(\\(,\\)\\|;\\|\\'\\)")) + (goto-char (or (scan-sexps (point) 1) (point-max)))) + (goto-char (match-end 2))) + (error t))))) + (defvar fortran-font-lock-keywords-3 (append fortran-font-lock-keywords-1 @@ -408,7 +432,7 @@ program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?" ;; Type specifier. '(1 font-lock-type-face) ;; Declaration item (or just /.../ block name). - `(font-lock-match-c-style-declaration-item-and-skip-to-next + `(fortran-match-and-skip-declaration ;; Start after any *(...) expression. (condition-case nil (and (match-beginning ,(1+ (regexp-opt-depth @@ -462,13 +486,22 @@ Consists of level 3 plus all other intrinsics not already highlighted.") ;; (We can do so for F90-style). Therefore an unmatched quote in a ;; standard comment will throw fontification off on the wrong track. ;; So we do syntactic fontification with regexps. -(defun fortran-font-lock-syntactic-keywords () - "Return a value for `font-lock-syntactic-keywords' in Fortran mode. -This varies according to the value of `fortran-line-length'. +(defun fortran-make-syntax-propertize-function (line-length) + "Return a value for `syntax-propertize-function' in Fortran mode. +This varies according to the value of LINE-LENGTH. This is used to fontify fixed-format Fortran comments." - `(("^[cd\\*]" 0 (11)) - (,(format "^[^cd\\*\t\n].\\{%d\\}\\([^\n]+\\)" (1- fortran-line-length)) - 1 (11)))) + ;; This results in a non-byte-compiled function. We could pass it through + ;; `byte-compile', but simple benchmarks indicate that it's probably not + ;; worth the trouble (about ½% of slow down). + (eval ;I hate `eval', but it's hard to avoid it here. + `(syntax-propertize-rules + ("^[cd\\*]" (0 "<")) + ;; We mark all chars after line-length as "comment-start", rather than + ;; just the first one. This is so that a closing ' that's past the + ;; line-length will indeed be ignored (and will result in a string that + ;; leaks into subsequent lines). + ((format "^[^cd\\*\t\n].\\{%d\\}\\(.+\\)" (1- line-length)) + (1 "<"))))) (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 "Default expressions to highlight in Fortran mode.") @@ -617,14 +650,21 @@ Used in the Fortran entry in `hs-special-modes-alist'.") (easy-menu-define fortran-menu map "Menu for Fortran mode." `("Fortran" - ["Manual" (info "(emacs)Fortran")] + ["Manual" (info "(emacs)Fortran") :active t + :help "Read the Emacs manual chapter on Fortran mode"] ("Customization" ,(custom-menu-create 'fortran) - ["Set" Custom-set t] - ["Save" Custom-save t] - ["Reset to Current" Custom-reset-current t] - ["Reset to Saved" Custom-reset-saved t] - ["Reset to Standard Settings" Custom-reset-standard t] + ;; FIXME useless? + ["Set" Custom-set :active t + :help "Set current value of all edited settings in the buffer"] + ["Save" Custom-save :active t + :help "Set and save all edited settings"] + ["Reset to Current" Custom-reset-current :active t + :help "Reset all edited settings to current"] + ["Reset to Saved" Custom-reset-saved :active t + :help "Reset all edited or set settings to saved"] + ["Reset to Standard Settings" Custom-reset-standard :active t + :help "Erase all cusomizations in buffer"] ) "--" ["Comment Region" fortran-comment-region mark-active] @@ -634,9 +674,12 @@ Used in the Fortran entry in `hs-special-modes-alist'.") ["Indent Region" indent-region mark-active] ["Indent Subprogram" fortran-indent-subprogram t] "--" - ["Beginning of Subprogram" fortran-beginning-of-subprogram t] - ["End of Subprogram" fortran-end-of-subprogram t] + ["Beginning of Subprogram" fortran-beginning-of-subprogram :active t + :help "Move point to the start of the current subprogram"] + ["End of Subprogram" fortran-end-of-subprogram :active t + :help "Move point to the end of the current subprogram"] ("Mark" + :help "Mark a region of code" ["Subprogram" mark-defun t] ["IF Block" fortran-mark-if t] ["DO Block" fortran-mark-do t] @@ -644,26 +687,34 @@ Used in the Fortran entry in `hs-special-modes-alist'.") ["Narrow to Subprogram" narrow-to-defun t] ["Widen" widen t] "--" - ["Temporary column ruler" fortran-column-ruler t] + ["Temporary Column Ruler" fortran-column-ruler :active t + :help "Briefly display Fortran column numbers"] ;; May not be '72', depending on fortran-line-length, but this ;; seems ok for a menu item. - ["72-column window" fortran-window-create t] + ["72-column Window" fortran-window-create :active t + :help "Set window width to Fortran line length"] ["Full Width Window" (enlarge-window-horizontally (- (frame-width) (window-width))) - (not (window-full-width-p))] - ["Momentary 72-column window" fortran-window-create-momentarily t] + :active (not (window-full-width-p)) + :help "Make window full width"] + ["Momentary 72-Column Window" fortran-window-create-momentarily + :active t :help "Briefly set window width to Fortran line length"] "--" - ["Break Line at Point" fortran-split-line t] - ["Join Line" fortran-join-line t] - ["Fill Statement/Comment" fill-paragraph t] + ["Break Line at Point" fortran-split-line :active t + :help "Break the current line at point"] + ["Join Line" fortran-join-line :active t + :help "Join the current line to the previous one"] + ["Fill Statement/Comment" fill-paragraph t] "--" - ["Toggle auto-fill" auto-fill-mode :selected auto-fill-function - :style toggle] - ["Toggle abbrev-mode" abbrev-mode :selected abbrev-mode - :style toggle] - ["Add imenu Menu" imenu-add-menubar-index + ["Toggle Auto Fill" auto-fill-mode :selected auto-fill-function + :style toggle + :help "Automatically fill text while typing in this buffer"] + ["Toggle Abbrev Mode" abbrev-mode :selected abbrev-mode + :style toggle :help "Expand abbreviations while typing in this buffer"] + ["Add Imenu Menu" imenu-add-menubar-index :active (not (lookup-key (current-local-map) [menu-bar index])) - :included (fboundp 'imenu-add-to-menubar)])) + :included (fboundp 'imenu-add-to-menubar) + :help "Add an index menu to the menu-bar"])) map) "Keymap used in Fortran mode.") @@ -734,7 +785,7 @@ Used in the Fortran entry in `hs-special-modes-alist'.") ;;;###autoload -(defun fortran-mode () +(define-derived-mode fortran-mode prog-mode "Fortran" "Major mode for editing Fortran code in fixed format. For free format code, use `f90-mode'. @@ -804,13 +855,9 @@ Variables controlling indentation style and extra features: Turning on Fortran mode calls the value of the variable `fortran-mode-hook' with no args, if that value is non-nil." - (interactive) - (kill-all-local-variables) - (setq major-mode 'fortran-mode - mode-name "Fortran" - local-abbrev-table fortran-mode-abbrev-table) - (set-syntax-table fortran-mode-syntax-table) - (use-local-map fortran-mode-map) + :group 'fortran + :syntax-table fortran-mode-syntax-table + :abbrev-table fortran-mode-abbrev-table (set (make-local-variable 'indent-line-function) 'fortran-indent-line) (set (make-local-variable 'indent-region-function) (lambda (start end) @@ -847,9 +894,9 @@ with no args, if that value is non-nil." fortran-font-lock-keywords-3 fortran-font-lock-keywords-4) nil t ((?/ . "$/") ("_$" . "w")) - fortran-beginning-of-subprogram - (font-lock-syntactic-keywords - . fortran-font-lock-syntactic-keywords))) + fortran-beginning-of-subprogram)) + (set (make-local-variable 'syntax-propertize-function) + (fortran-make-syntax-propertize-function fortran-line-length)) (set (make-local-variable 'imenu-case-fold-search) t) (set (make-local-variable 'imenu-generic-expression) fortran-imenu-generic-expression) @@ -862,33 +909,37 @@ with no args, if that value is non-nil." #'fortran-current-defun) (set (make-local-variable 'dabbrev-case-fold-search) 'case-fold-search) (set (make-local-variable 'gud-find-expr-function) 'fortran-gud-find-expr) - (add-hook 'hack-local-variables-hook 'fortran-hack-local-variables nil t) - (run-mode-hooks 'fortran-mode-hook)) + (add-hook 'hack-local-variables-hook 'fortran-hack-local-variables nil t)) (defun fortran-line-length (nchars &optional global) "Set the length of fixed-form Fortran lines to NCHARS. This normally only affects the current buffer, which must be in Fortran mode. If the optional argument GLOBAL is non-nil, it -affects all Fortran buffers, and also the default." - (interactive "p") - (let (new) - (mapc (lambda (buff) - (with-current-buffer buff - (when (eq major-mode 'fortran-mode) - (setq fortran-line-length nchars - fill-column fortran-line-length - new (fortran-font-lock-syntactic-keywords)) - ;; Refontify only if necessary. - (unless (equal new font-lock-syntactic-keywords) - (setq font-lock-syntactic-keywords - (fortran-font-lock-syntactic-keywords)) - (if font-lock-mode (font-lock-mode 1)))))) +affects all Fortran buffers, and also the default. +If a numeric prefix argument is specified, it will be used as NCHARS, +otherwise is a non-numeric prefix arg is specified, the length will be +provided via the minibuffer, and otherwise the current column is used." + (interactive + (list (cond + ((numberp current-prefix-arg) current-prefix-arg) + (current-prefix-arg + (read-number "Line length: " (default-value 'fortran-line-length))) + (t (current-column))))) + (dolist (buff (if global + (buffer-list) + (list (current-buffer)))) + (with-current-buffer buff + (when (derived-mode-p 'fortran-mode) + (unless (eq fortran-line-length nchars) + (setq fortran-line-length nchars + fill-column fortran-line-length + syntax-propertize-function + (fortran-make-syntax-propertize-function nchars)) + (syntax-ppss-flush-cache (point-min)) + (if font-lock-mode (font-lock-mode 1)))))) (if global - (buffer-list) - (list (current-buffer)))) - (if global - (setq-default fortran-line-length nchars)))) + (setq-default fortran-line-length nchars))) (defun fortran-hack-local-variables () "Fortran mode adds this to `hack-local-variables-hook'." @@ -986,7 +1037,7 @@ With non-nil ARG, uncomments the region." "Typing ;\\[help-command] or ;? lists all the Fortran abbrevs. Any other key combination is executed normally." (interactive "*") - (insert last-command-char) + (insert last-command-event) (let* ((event (if (fboundp 'next-command-event) ; XEmacs (next-command-event) (read-event))) @@ -1147,7 +1198,7 @@ Auto-indent does not happen if a numeric ARG is used." (looking-at "[0-9]")) ; within a line number (self-insert-command (prefix-numeric-value arg)) (skip-chars-backward " \t") - (insert last-command-char) + (insert last-command-event) (fortran-indent-line)))) @@ -1162,37 +1213,47 @@ Auto-indent does not happen if a numeric ARG is used." (+ fortran-line-length (line-beginning-position))))))) -;; Note that you can't just check backwards for `subroutine' &c in -;; case of un-marked main programs not at the start of the file. +;; This is more complex than first expected because the beginning of a +;; main program may be implicit (ie not marked by a PROGRAM statement). +;; This would be fine (we could just go to bob in the absence of a match), +;; except it need not even be the first subprogram in the file (eg it +;; could follow a subroutine). Hence we have to search for END +;; statements instead. +;; cf fortran-beginning-of-block, f90-beginning-of-subprogram +;; Note that unlike the latter, we don't have to worry about nested +;; subprograms (?). +;; FIXME push-mark? (defun fortran-beginning-of-subprogram () "Move point to the beginning of the current Fortran subprogram." (interactive) - (save-match-data - (let ((case-fold-search t)) - (beginning-of-line -1) - (if (catch 'ok - (while (re-search-backward fortran-end-prog-re nil 'move) - (if (fortran-check-end-prog-re) - (throw 'ok t)))) - (forward-line))))) - + (let ((case-fold-search t)) + ;; If called already at the start of subprogram, go to the previous. + (beginning-of-line (if (bolp) 0 1)) + (save-match-data + (or (looking-at fortran-start-prog-re) + ;; This leaves us at bob if before the first subprogram. + (eq (fortran-previous-statement) 'first-statement) + (if (or (catch 'ok + (while (re-search-backward fortran-end-prog-re nil 'move) + (if (fortran-check-end-prog-re) (throw 'ok t)))) + ;; If the search failed, must be at bob. + ;; First code line is the start of the subprogram. + ;; FIXME use a more rigorous test, cf fortran-next-statement? + ;; Though that needs to handle continuations too. + (not (looking-at "^\\([ \t]*[0-9]\\|[ \t]+[^!#]\\)"))) + (fortran-next-statement)))))) + +;; This is simpler than f-beginning-of-s because the end of a +;; subprogram is never implicit. (defun fortran-end-of-subprogram () "Move point to the end of the current Fortran subprogram." (interactive) - (save-match-data - (let ((case-fold-search t)) - (if (save-excursion ; on END - (beginning-of-line) - (and (looking-at fortran-end-prog-re) - (fortran-check-end-prog-re))) - (forward-line) - (beginning-of-line 2) - (when (catch 'ok - (while (re-search-forward fortran-end-prog-re nil 'move) - (if (fortran-check-end-prog-re) - (throw 'ok t)))) - (goto-char (match-beginning 0)) - (forward-line)))))) + (let ((case-fold-search t)) + (beginning-of-line) + (save-match-data + (while (and (re-search-forward fortran-end-prog-re nil 'move) + (not (fortran-check-end-prog-re)))) + (forward-line)))) (defun fortran-previous-statement () "Move point to beginning of the previous Fortran statement. @@ -1252,8 +1313,7 @@ Directive lines are treated as comments." (if i (save-excursion (goto-char i) - (beginning-of-line) - (= (point) p))))) + (= (line-beginning-position) p))))) ;; Used in hs-special-modes-alist. (defun fortran-end-of-block (&optional num) @@ -1263,7 +1323,7 @@ If NUM is negative, go backward to the start of a block. Does not check for consistency of block types. Interactively, pushes mark before moving point." (interactive "p") - (if (interactive-p) (push-mark (point) t)) + (if (called-interactively-p 'any) (push-mark (point) t)) (and num (< num 0) (fortran-beginning-of-block (- num))) (let ((case-fold-search t) (count (or num 1))) @@ -1296,7 +1356,7 @@ blocks. If NUM is negative, go forward to the end of a block. Does not check for consistency of block types. Interactively, pushes mark before moving point." (interactive "p") - (if (interactive-p) (push-mark (point) t)) + (if (called-interactively-p 'any) (push-mark (point) t)) (and num (< num 0) (fortran-end-of-block (- num))) (let ((case-fold-search t) (count (or num 1))) @@ -2117,19 +2177,16 @@ arg DO-SPACE prevents stripping the whitespace." (replace-match "" nil nil nil 1) (unless do-space (delete-horizontal-space))))) -;; This code used to live in add-log.el, but this is a better place -;; for it. +;; This code used to live in add-log.el, but this is a better place for it. (defun fortran-current-defun () "Function to use for `add-log-current-defun-function' in Fortran mode." (save-excursion ;; We must be inside function body for this to work. (fortran-beginning-of-subprogram) - (let ((case-fold-search t)) ; case-insensitive + (let ((case-fold-search t)) ;; Search for fortran subprogram start. (if (re-search-forward - (concat "^[ \t]*\\(program\\|subroutine\\|function" - "\\|[ \ta-z0-9*()]*[ \t]+function\\|" - "\\(block[ \t]*data\\)\\)") + fortran-start-prog-re (save-excursion (fortran-end-of-subprogram) (point)) t) @@ -2147,5 +2204,4 @@ arg DO-SPACE prevents stripping the whitespace." (provide 'fortran) -;; arch-tag: 74935096-21c4-4cab-8ee5-6ef16090dc04 ;;; fortran.el ends here