X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b03f96dc5a6651d1dc84b81b2a15cad6908b9809..cd9b5d3e5194b2c2da7ed83ab8759a9503cb4ee8:/lisp/progmodes/fortran.el diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index a8d780753f..bfc95479ce 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el @@ -10,10 +10,10 @@ ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -21,9 +21,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -98,7 +96,8 @@ 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 :group 'fortran-indent) (put 'fortran-tab-mode-string 'risky-local-variable t) @@ -149,7 +148,8 @@ nil forces comment lines not to be touched; (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 :group 'fortran-comment) @@ -226,7 +226,7 @@ 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 :group 'fortran) (put 'fortran-continuation-string 'safe-local-variable @@ -391,8 +391,8 @@ program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?" 'paren) "\\>") ;; Builtin operators. (concat "\\." (regexp-opt - '("and" "or" "not" "lt" "le" "eq" "ge" - "gt" "ne" "true" "false") + '("and" "eq" "eqv" "false" "ge" "gt" "le" "lt" "ne" + "neqv" "not" "or" "true") 'paren) "\\.") ;; do/goto keywords and targets, and goto tags. '("\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?" @@ -560,9 +560,9 @@ Used in the Fortran entry in `hs-special-modes-alist'.") (defvar fortran-mode-syntax-table (let ((table (make-syntax-table))) - ;; We might like `;' to be punctuation (g77 multi-statement - ;; lines), but that screws abbrevs. - (modify-syntax-entry ?\; "w" table) + ;; Was a word-constituent (for abbrevs), now punctuation (g77 + ;; multi-statement lines). + (modify-syntax-entry ?\; "." table) (modify-syntax-entry ?\r " " table) (modify-syntax-entry ?+ "." table) (modify-syntax-entry ?- "." table) @@ -670,81 +670,69 @@ Used in the Fortran entry in `hs-special-modes-alist'.") "Keymap used in Fortran mode.") -(defvar fortran-mode-abbrev-table - (progn - (define-abbrev-table 'fortran-mode-abbrev-table nil) - fortran-mode-abbrev-table) - "Abbrev table for Fortran mode.") - -(let (abbrevs-changed) - ;; Use the 6th arg (SYSTEM-FLAG) of define-abbrev if possible. - ;; Only use `apply' to quieten the byte-compiler. - (mapc - (function (lambda (element) - (condition-case nil - (apply 'define-abbrev fortran-mode-abbrev-table - (append element '(nil 0 t))) - (wrong-number-of-arguments - (apply 'define-abbrev fortran-mode-abbrev-table - (append element '(nil 0))))))) - '((";au" "automatic" ) - (";b" "byte" ) - (";bd" "block data" ) - (";ch" "character" ) - (";cl" "close" ) - (";c" "continue" ) - (";cm" "common" ) - (";cx" "complex" ) - (";df" "define" ) - (";di" "dimension" ) - (";do" "double" ) - (";dc" "double complex" ) - (";dp" "double precision" ) - (";dw" "do while" ) - (";e" "else" ) - (";ed" "enddo" ) - (";el" "elseif" ) - (";en" "endif" ) - (";eq" "equivalence" ) - (";ew" "endwhere" ) - (";ex" "external" ) - (";ey" "entry" ) - (";f" "format" ) - (";fa" ".false." ) - (";fu" "function" ) - (";g" "goto" ) - (";im" "implicit" ) - (";ib" "implicit byte" ) - (";ic" "implicit complex" ) - (";ich" "implicit character") - (";ii" "implicit integer" ) - (";il" "implicit logical" ) - (";ir" "implicit real" ) - (";inc" "include" ) - (";in" "integer" ) - (";intr" "intrinsic" ) - (";l" "logical" ) - (";n" "namelist" ) - (";o" "open" ) ; was ;op - (";pa" "parameter" ) - (";pr" "program" ) - (";ps" "pause" ) - (";p" "print" ) - (";rc" "record" ) - (";re" "real" ) - (";r" "read" ) - (";rt" "return" ) - (";rw" "rewind" ) - (";s" "stop" ) - (";sa" "save" ) - (";st" "structure" ) - (";sc" "static" ) - (";su" "subroutine" ) - (";tr" ".true." ) - (";ty" "type" ) - (";vo" "volatile" ) - (";w" "write" ) - (";wh" "where" )))) +(define-abbrev-table 'fortran-mode-abbrev-table + (mapcar (lambda (e) (list (car e) (cdr e) nil :system t)) + '((";au" . "automatic" ) + (";b" . "byte" ) + (";bd" . "block data" ) + (";ch" . "character" ) + (";cl" . "close" ) + (";c" . "continue" ) + (";cm" . "common" ) + (";cx" . "complex" ) + (";df" . "define" ) + (";di" . "dimension" ) + (";do" . "double" ) + (";dc" . "double complex" ) + (";dp" . "double precision" ) + (";dw" . "do while" ) + (";e" . "else" ) + (";ed" . "enddo" ) + (";el" . "elseif" ) + (";en" . "endif" ) + (";eq" . "equivalence" ) + (";ew" . "endwhere" ) + (";ex" . "external" ) + (";ey" . "entry" ) + (";f" . "format" ) + (";fa" . ".false." ) + (";fu" . "function" ) + (";g" . "goto" ) + (";im" . "implicit" ) + (";ib" . "implicit byte" ) + (";ic" . "implicit complex" ) + (";ich" . "implicit character") + (";ii" . "implicit integer" ) + (";il" . "implicit logical" ) + (";ir" . "implicit real" ) + (";inc" . "include" ) + (";in" . "integer" ) + (";intr" . "intrinsic" ) + (";l" . "logical" ) + (";n" . "namelist" ) + (";o" . "open" ) ; was ;op + (";pa" . "parameter" ) + (";pr" . "program" ) + (";ps" . "pause" ) + (";p" . "print" ) + (";rc" . "record" ) + (";re" . "real" ) + (";r" . "read" ) + (";rt" . "return" ) + (";rw" . "rewind" ) + (";s" . "stop" ) + (";sa" . "save" ) + (";st" . "structure" ) + (";sc" . "static" ) + (";su" . "subroutine" ) + (";tr" . ".true." ) + (";ty" . "type" ) + (";vo" . "volatile" ) + (";w" . "write" ) + (";wh" . "where" ))) + "Abbrev table for Fortran mode." + ;; Accept ; as the first char of an abbrev. Also allow _ in abbrevs. + :regexp "\\(?:[^[:word:]_;]\\|^\\)\\(;?[[:word:]_]+\\)[^[:word:]_]*") ;;;###autoload @@ -863,7 +851,7 @@ with no args, if that value is non-nil." nil t ((?/ . "$/") ("_$" . "w")) fortran-beginning-of-subprogram (font-lock-syntactic-keywords - . (fortran-font-lock-syntactic-keywords)))) + . fortran-font-lock-syntactic-keywords))) (set (make-local-variable 'imenu-case-fold-search) t) (set (make-local-variable 'imenu-generic-expression) fortran-imenu-generic-expression) @@ -1201,12 +1189,12 @@ Auto-indent does not happen if a numeric ARG is used." (fortran-check-end-prog-re))) (forward-line) (beginning-of-line 2) - (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))))) + (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)))))) (defun fortran-previous-statement () "Move point to beginning of the previous Fortran statement. @@ -1665,7 +1653,17 @@ Return point or nil." ((and (looking-at fortran-end-prog-re1) (fortran-check-end-prog-re)) ;; Previous END resets indent to minimum. - (setq icol fortran-minimum-statement-indent))))) + (setq icol fortran-minimum-statement-indent)) + ;; Previous statement was a numbered DO loop without a + ;; closing CONTINUE or END DO, so we indented the + ;; terminator like the loop body. + ((and fortran-check-all-num-for-matching-do + (not (looking-at "\\(continue\\|end[ \t]*do\\)\\>")) + (progn + (beginning-of-line) + (and (looking-at "[ \t]*[0-9]+") + (fortran-check-for-matching-do)))) + (setq icol (- icol fortran-do-indent)))))) (save-excursion (beginning-of-line) (cond ((looking-at "[ \t]*$")) @@ -1690,8 +1688,12 @@ Return point or nil." 6 (+ icol fortran-continuation-indent)))) (first-statement) + ;; The terminating statement is actually part of the + ;; loop body, so unless it is a CONTINUE or END DO, we + ;; indent it like the loop body (see above). ((and fortran-check-all-num-for-matching-do - (looking-at "[ \t]*[0-9]+") + (looking-at "[ \t]*[0-9]+[ \t]*\ +\\(continue\\|end[ \t]*do\\)\\>") (fortran-check-for-matching-do)) (setq icol (- icol fortran-do-indent))) (t