diff options
| author | Dave Love | 1998-04-07 18:59:44 +0000 |
|---|---|---|
| committer | Dave Love | 1998-04-07 18:59:44 +0000 |
| commit | 1eb6bf70dcd005d90b0049ea9f9b74881a2e335e (patch) | |
| tree | dbc1d24704f7510a4893a86e5f8521188cb7314e | |
| parent | 15171a06d35ecbe33a98aa48751e47a717684bcd (diff) | |
| download | emacs-1eb6bf70dcd005d90b0049ea9f9b74881a2e335e.tar.gz emacs-1eb6bf70dcd005d90b0049ea9f9b74881a2e335e.zip | |
Use regexp-opt and eval-and-compile to
build font-lock patterns.
(fortran-mode): Define indent-region-function,
indent-line-function.
(fortran-tab-mode-string): Make buffer-local.
(fortran-comment-indent-style): Custom tweak.
(fortran-comment-region, fortran-electric-line-number,
fortran-analyze-depth, fortran-break-before-delimiters,
fortran-mode): Doc fix.
(fortran-startup-message, bug-fortran-mode): Variables
deleted.
(fortran-font-lock-keywords-1): Add "select", "case"; allow
double-quoted strings.
(fortran-mode-map): Add fill-paragraph menu item. Don't
define \t.
(fortran-mode): Make `fill-column' buffer-local; set
`fill-paragraph-function', `indent-region-function',
`indent-line-function'.
(calculate-fortran-indent): Renamed to:
(fortran-calculate-indent):
(fortran-split-line): Simplify.
(fortran-remove-continuation): New function.
(fortran-join-line): Use it.
(fortran-end-prog-re1, fortran-end-prog-re): New variables.
(beginning-of-fortran-subprogram, end-of-fortran-subprogram):
Use them.
(fortran-blink-matching-if, fortran-blink-matching-do,
fortran-indent-new-line): Bind case-fold-search.
(fortran-end-do, fortran-beginning-do, fortran-end-if,
fortran-beginning-if): Bind case-fold-search. Allow labelled
blocks. Use fortran-end-prog-re.
(fortran-if-start-re): New variable.
(fortran-calculate-indent): Allow labelled blocks. Simplify the
conds. Make select case indentation work.
(fortran-is-in-string-p): Ignore Emacs 18 bug kluge.
(fortran-fill): Allow double quotes in check for string.
(fortran-fill-paragraph): New function.
(fortran-fill-statement): New function.
| -rw-r--r-- | lisp/progmodes/fortran.el | 737 |
1 files changed, 403 insertions, 334 deletions
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index 4b38c30cd0b..a20b42a19b5 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el | |||
| @@ -42,6 +42,13 @@ | |||
| 42 | 42 | ||
| 43 | ;;; Code: | 43 | ;;; Code: |
| 44 | 44 | ||
| 45 | ;; Todo: | ||
| 46 | |||
| 47 | ;; * Implement insertion and removal of statement continuations in | ||
| 48 | ;; mixed f77/f90 style, with the first `&' past column 72 and the | ||
| 49 | ;; second in column 6. | ||
| 50 | ;; * Support other f90-style stuff grokked by GNU Fortran. | ||
| 51 | |||
| 45 | (require 'easymenu) | 52 | (require 'easymenu) |
| 46 | 53 | ||
| 47 | (defgroup fortran nil | 54 | (defgroup fortran nil |
| @@ -73,6 +80,7 @@ with a character in column 6." | |||
| 73 | "String to appear in mode line when TAB format mode is on." | 80 | "String to appear in mode line when TAB format mode is on." |
| 74 | :type '(choice (const nil) string) | 81 | :type '(choice (const nil) string) |
| 75 | :group 'fortran-indent) | 82 | :group 'fortran-indent) |
| 83 | (make-variable-buffer-local 'fortran-tab-mode-string) | ||
| 76 | 84 | ||
| 77 | (defcustom fortran-do-indent 3 | 85 | (defcustom fortran-do-indent 3 |
| 78 | "*Extra indentation applied to DO blocks." | 86 | "*Extra indentation applied to DO blocks." |
| @@ -102,7 +110,7 @@ columns beyond `fortran-minimum-statement-indent-fixed' (for | |||
| 102 | `indent-tabs-mode' of nil) or `fortran-minimum-statement-indent-tab' (for | 110 | `indent-tabs-mode' of nil) or `fortran-minimum-statement-indent-tab' (for |
| 103 | `indent-tabs-mode' of t), and 'relative indents to current | 111 | `indent-tabs-mode' of t), and 'relative indents to current |
| 104 | Fortran indentation plus `fortran-comment-line-extra-indent'." | 112 | Fortran indentation plus `fortran-comment-line-extra-indent'." |
| 105 | :type '(radio (const nil) (const fixed) (const relative)) | 113 | :type '(radio (const :tag "Untouched" nil) (const fixed) (const relative)) |
| 106 | :group 'fortran-indent) | 114 | :group 'fortran-indent) |
| 107 | 115 | ||
| 108 | (defcustom fortran-comment-line-extra-indent 0 | 116 | (defcustom fortran-comment-line-extra-indent 0 |
| @@ -168,19 +176,14 @@ Normally $." | |||
| 168 | :group 'fortran) | 176 | :group 'fortran) |
| 169 | 177 | ||
| 170 | (defcustom fortran-comment-region "c$$$" | 178 | (defcustom fortran-comment-region "c$$$" |
| 171 | "*String inserted by \\[fortran-comment-region]\ | 179 | "*String inserted by \\[fortran-comment-region] at start of each \ |
| 172 | at start of each line in region." | 180 | line in region." |
| 173 | :type 'string | 181 | :type 'string |
| 174 | :group 'fortran-comment) | 182 | :group 'fortran-comment) |
| 175 | 183 | ||
| 176 | (defcustom fortran-electric-line-number t | 184 | (defcustom fortran-electric-line-number t |
| 177 | "*Non-nil causes line number digits to be moved to the correct column as\ | 185 | "*Non-nil causes line number digits to be moved to the correct \ |
| 178 | typed." | 186 | column as typed." |
| 179 | :type 'boolean | ||
| 180 | :group 'fortran) | ||
| 181 | |||
| 182 | (defcustom fortran-startup-message t | ||
| 183 | "*Non-nil displays a startup message when Fortran mode is first called." | ||
| 184 | :type 'boolean | 187 | :type 'boolean |
| 185 | :group 'fortran) | 188 | :group 'fortran) |
| 186 | 189 | ||
| @@ -204,11 +207,11 @@ This variable used in TAB format mode.") | |||
| 204 | "Syntax table in use in Fortran mode buffers.") | 207 | "Syntax table in use in Fortran mode buffers.") |
| 205 | 208 | ||
| 206 | (defvar fortran-analyze-depth 100 | 209 | (defvar fortran-analyze-depth 100 |
| 207 | "Number of lines to scan to determine whether to use fixed or TAB format\ | 210 | "Number of lines to scan to determine whether to use fixed or TAB \ |
| 208 | style.") | 211 | format style.") |
| 209 | 212 | ||
| 210 | (defcustom fortran-break-before-delimiters t | 213 | (defcustom fortran-break-before-delimiters t |
| 211 | "*Non-nil causes `fortran-fill' to break lines before delimiters." | 214 | "*Non-nil causes filling to break lines before delimiters." |
| 212 | :type 'boolean | 215 | :type 'boolean |
| 213 | :group 'fortran) | 216 | :group 'fortran) |
| 214 | 217 | ||
| @@ -252,115 +255,109 @@ style.") | |||
| 252 | (defconst fortran-font-lock-keywords-3 nil | 255 | (defconst fortran-font-lock-keywords-3 nil |
| 253 | "Gaudy level highlighting for Fortran mode.") | 256 | "Gaudy level highlighting for Fortran mode.") |
| 254 | 257 | ||
| 255 | (let ((comment-chars "c!*") | 258 | (eval-and-compile |
| 256 | (fortran-type-types | 259 | (let ((comment-chars "c!*") |
| 257 | ; (make-regexp | 260 | (fortran-type-types |
| 258 | ; (let ((simple-types '("character" "byte" "integer" "logical" | 261 | (regexp-opt |
| 259 | ; "none" "real" "complex" | 262 | (let ((simple-types '("character" "byte" "integer" "logical" |
| 260 | ; "double[ \t]*precision" "double[ \t]*complex")) | 263 | "none" "real" "complex" |
| 261 | ; (structured-types '("structure" "union" "map")) | 264 | "double[ \t]*precision" "double[ \t]*complex")) |
| 262 | ; (other-types '("record" "dimension" "parameter" "common" "save" | 265 | (structured-types '("structure" "union" "map")) |
| 263 | ; "external" "intrinsic" "data" "equivalence"))) | 266 | (other-types '("record" "dimension" "parameter" "common" "save" |
| 264 | ; (append | 267 | "external" "intrinsic" "data" "equivalence"))) |
| 265 | ; (mapcar (lambda (x) (concat "implicit[ \t]*" x)) simple-types) | 268 | (append |
| 266 | ; simple-types | 269 | (mapcar (lambda (x) (concat "implicit[ \t]*" x)) simple-types) |
| 267 | ; (mapcar (lambda (x) (concat "end[ \t]*" x)) structured-types) | 270 | simple-types |
| 268 | ; structured-types | 271 | (mapcar (lambda (x) (concat "end[ \t]*" x)) structured-types) |
| 269 | ; other-types))) | 272 | structured-types |
| 270 | (concat "byte\\|c\\(haracter\\|om\\(mon\\|plex\\)\\)\\|" | 273 | other-types)))) |
| 271 | "d\\(ata\\|imension\\|ouble" | 274 | (fortran-keywords |
| 272 | "[ \t]*\\(complex\\|precision\\)\\)\\|" | 275 | (regexp-opt '("continue" "format" "end" "enddo" "if" "then" |
| 273 | "e\\(nd[ \t]*\\(map\\|structure\\|union\\)\\|" | 276 | "else" "endif" "elseif" "while" "inquire" "stop" |
| 274 | "quivalence\\|xternal\\)\\|" | 277 | "return" "include" "open" "close" "read" "write" |
| 275 | "i\\(mplicit[ \t]*\\(byte\\|" | 278 | "format" "print" "select" "case"))) |
| 276 | "c\\(haracter\\|omplex\\)\\|" | ||
| 277 | "double[ \t]*\\(complex\\|precision\\)\\|" | ||
| 278 | "integer\\|logical\\|none\\|real\\)\\|" | ||
| 279 | "nt\\(eger\\|rinsic\\)\\)\\|" | ||
| 280 | "logical\\|map\\|none\\|parameter\\|re\\(al\\|cord\\)\\|" | ||
| 281 | "s\\(ave\\|tructure\\)\\|union")) | ||
| 282 | (fortran-keywords | ||
| 283 | ; ("continue" "format" "end" "enddo" "if" "then" "else" "endif" | ||
| 284 | ; "elseif" "while" "inquire" "stop" "return" "include" "open" | ||
| 285 | ; "close" "read" "write" "format" "print") | ||
| 286 | (concat "c\\(lose\\|ontinue\\)\\|" | ||
| 287 | "e\\(lse\\(\\|if\\)\\|nd\\(\\|do\\|if\\)\\)\\|format\\|" | ||
| 288 | "i\\(f\\|n\\(clude\\|quire\\)\\)\\|open\\|print\\|" | ||
| 289 | "re\\(ad\\|turn\\)\\|stop\\|then\\|w\\(hile\\|rite\\)")) | ||
| 290 | (fortran-logicals | 279 | (fortran-logicals |
| 291 | ; ("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne" "true" "false") | 280 | (regexp-opt '("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne" |
| 292 | "and\\|eq\\|false\\|g[et]\\|l[et]\\|n\\(e\\|ot\\)\\|or\\|true")) | 281 | "true" "false")))) |
| 293 | 282 | ||
| 294 | (setq fortran-font-lock-keywords-1 | 283 | (setq fortran-font-lock-keywords-1 |
| 295 | (list | 284 | (list |
| 296 | ;; | 285 | ;; |
| 297 | ;; Fontify syntactically (assuming strings cannot be quoted or span lines). | 286 | ;; Fontify syntactically (assuming strings cannot be quoted |
| 298 | (cons (concat "^[" comment-chars "].*") 'font-lock-comment-face) | 287 | ;; or span lines). |
| 299 | '(fortran-match-!-comment . font-lock-comment-face) | 288 | (cons (concat "^[" comment-chars "].*") 'font-lock-comment-face) |
| 300 | (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.) "\\(.*\\)") | 289 | '(fortran-match-!-comment . font-lock-comment-face) |
| 301 | '(1 font-lock-comment-face)) | 290 | (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.) |
| 302 | '("'[^'\n]*'?" . font-lock-string-face) | 291 | "\\(.*\\)") |
| 303 | ;; | 292 | '(1 font-lock-comment-face)) |
| 304 | ;; Program, subroutine and function declarations, plus calls. | 293 | '("\\(\\s\"\\)\"[^\n]*\\1?" . font-lock-string-face) |
| 305 | (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|" | 294 | ;; |
| 306 | "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?") | 295 | ;; Program, subroutine and function declarations, plus calls. |
| 307 | '(1 font-lock-keyword-face) | 296 | (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|" |
| 308 | '(2 font-lock-function-name-face nil t)))) | 297 | "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?") |
| 309 | 298 | '(1 font-lock-keyword-face) | |
| 310 | (setq fortran-font-lock-keywords-2 | 299 | '(2 font-lock-function-name-face nil t)))) |
| 311 | (append fortran-font-lock-keywords-1 | 300 | |
| 312 | (list | 301 | (setq fortran-font-lock-keywords-2 |
| 313 | ;; | 302 | (append fortran-font-lock-keywords-1 |
| 314 | ;; Fontify all type specifiers (must be first; see below). | 303 | (list |
| 315 | (cons (concat "\\<\\(" fortran-type-types "\\)\\>") 'font-lock-type-face) | 304 | ;; |
| 316 | ;; | 305 | ;; Fontify all type specifiers (must be first; see below). |
| 317 | ;; Fontify all builtin keywords (except logical, do and goto; see below). | 306 | (cons (concat "\\<\\(" fortran-type-types "\\)\\>") |
| 318 | (concat "\\<\\(" fortran-keywords "\\)\\>") | 307 | 'font-lock-type-face) |
| 319 | ;; | 308 | ;; |
| 320 | ;; Fontify all builtin operators. | 309 | ;; Fontify all builtin keywords (except logical, do |
| 321 | (concat "\\.\\(" fortran-logicals "\\)\\.") | 310 | ;; and goto; see below). |
| 322 | ;; | 311 | (concat "\\<\\(" fortran-keywords "\\)\\>") |
| 323 | ;; Fontify do/goto keywords and targets, and goto tags. | 312 | ;; |
| 324 | (list "\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?" | 313 | ;; Fontify all builtin operators. |
| 325 | '(1 font-lock-keyword-face) | 314 | (concat "\\.\\(" fortran-logicals "\\)\\.") |
| 326 | '(2 font-lock-constant-face nil t)) | 315 | ;; |
| 327 | (cons "^ *\\([0-9]+\\)" 'font-lock-constant-face)))) | 316 | ;; Fontify do/goto keywords and targets, and goto tags. |
| 328 | 317 | (list "\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?" | |
| 329 | (setq fortran-font-lock-keywords-3 | 318 | '(1 font-lock-keyword-face) |
| 330 | (append | 319 | '(2 font-lock-constant-face nil t)) |
| 331 | ;; | 320 | (cons "^ *\\([0-9]+\\)" 'font-lock-constant-face)))) |
| 332 | ;; The list `fortran-font-lock-keywords-1'. | 321 | |
| 333 | fortran-font-lock-keywords-1 | 322 | (setq fortran-font-lock-keywords-3 |
| 334 | ;; | 323 | (append |
| 335 | ;; Fontify all type specifiers plus their declared items. | 324 | ;; |
| 336 | (list | 325 | ;; The list `fortran-font-lock-keywords-1'. |
| 337 | (list (concat "\\<\\(" fortran-type-types "\\)\\>[ \t(/]*\\(*\\)?") | 326 | fortran-font-lock-keywords-1 |
| 338 | ;; Fontify the type specifier. | 327 | ;; |
| 339 | '(1 font-lock-type-face) | 328 | ;; Fontify all type specifiers plus their declared items. |
| 340 | ;; Fontify each declaration item (or just the /.../ block name). | 329 | (list |
| 341 | '(font-lock-match-c-style-declaration-item-and-skip-to-next | 330 | (list (concat "\\<\\(" fortran-type-types "\\)\\>[ \t(/]*\\(*\\)?") |
| 342 | ;; Start after any *(...) expression. | 331 | ;; Fontify the type specifier. |
| 343 | (and (match-beginning 15) (forward-sexp 1)) | 332 | '(1 font-lock-type-face) |
| 344 | ;; No need to clean up. | 333 | ;; Fontify each declaration item (or just the /.../ block name). |
| 345 | nil | 334 | '(font-lock-match-c-style-declaration-item-and-skip-to-next |
| 346 | ;; Fontify as a variable name, functions are fontified elsewhere. | 335 | ;; Start after any *(...) expression. |
| 347 | (1 font-lock-variable-name-face nil t)))) | 336 | (and (match-beginning 15) (forward-sexp)) |
| 348 | ;; | 337 | ;; No need to clean up. |
| 349 | ;; Things extra to `fortran-font-lock-keywords-3' (must be done first). | 338 | nil |
| 350 | (list | 339 | ;; Fontify as a variable name, functions are |
| 351 | ;; | 340 | ;; fontified elsewhere. |
| 352 | ;; Fontify goto-like `err=label'/`end=label' in read/write statements. | 341 | (1 font-lock-variable-name-face nil t)))) |
| 353 | '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?" | 342 | ;; |
| 354 | (1 font-lock-keyword-face) (4 font-lock-constant-face nil t)) | 343 | ;; Things extra to `fortran-font-lock-keywords-3' |
| 355 | ;; | 344 | ;; (must be done first). |
| 356 | ;; Highlight standard continuation character and in a TAB-formatted line. | 345 | (list |
| 357 | '("^ \\([^ 0]\\)" 1 font-lock-string-face) | 346 | ;; |
| 358 | '("^\t\\([1-9]\\)" 1 font-lock-string-face)) | 347 | ;; Fontify goto-like `err=label'/`end=label' in read/write |
| 359 | ;; | 348 | ;; statements. |
| 360 | ;; The list `fortran-font-lock-keywords-2' less that for types (see above). | 349 | '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?" |
| 361 | (cdr (nthcdr (length fortran-font-lock-keywords-1) | 350 | (1 font-lock-keyword-face) (4 font-lock-constant-face nil t)) |
| 362 | fortran-font-lock-keywords-2)))) | 351 | ;; |
| 363 | ) | 352 | ;; Highlight standard continuation character and in a |
| 353 | ;; TAB-formatted line. | ||
| 354 | '("^ \\([^ 0]\\)" 1 font-lock-string-face) | ||
| 355 | '("^\t\\([1-9]\\)" 1 font-lock-string-face)) | ||
| 356 | ;; | ||
| 357 | ;; The list `fortran-font-lock-keywords-2' less that for types | ||
| 358 | ;; (see above). | ||
| 359 | (cdr (nthcdr (length fortran-font-lock-keywords-1) | ||
| 360 | fortran-font-lock-keywords-2)))))) | ||
| 364 | 361 | ||
| 365 | (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 | 362 | (defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 |
| 366 | "Default expressions to highlight in Fortran mode.") | 363 | "Default expressions to highlight in Fortran mode.") |
| @@ -378,8 +375,9 @@ style.") | |||
| 378 | ;; index. [This will be fooled by `end function' allowed by G77. | 375 | ;; index. [This will be fooled by `end function' allowed by G77. |
| 379 | ;; Also, it assumes sensible whitespace is employed.] | 376 | ;; Also, it assumes sensible whitespace is employed.] |
| 380 | (concat "^\\s-+\\(\ | 377 | (concat "^\\s-+\\(\ |
| 381 | \\(\\sw\\|\\s-\\|[*()+]\\)*\\<function\\|\ | 378 | \\(\\sw\\|\\s-\\|[*()+]\\)*\ |
| 382 | subroutine\\|entry\\|block\\s-*data\\|program\\)[ \t" fortran-continuation-string "]+\ | 379 | \\<function\\|subroutine\\|entry\\|block\\s-*data\\|program\\)\ |
| 380 | [ \t" fortran-continuation-string "]+\ | ||
| 383 | \\(\\sw+\\)") | 381 | \\(\\sw+\\)") |
| 384 | 3) | 382 | 3) |
| 385 | ;; Un-named block data | 383 | ;; Un-named block data |
| @@ -406,7 +404,7 @@ subroutine\\|entry\\|block\\s-*data\\|program\\)[ \t" fortran-continuation-strin | |||
| 406 | (define-key fortran-mode-map "\C-c\C-n" 'fortran-next-statement) | 404 | (define-key fortran-mode-map "\C-c\C-n" 'fortran-next-statement) |
| 407 | (define-key fortran-mode-map "\C-c\C-d" 'fortran-join-line) | 405 | (define-key fortran-mode-map "\C-c\C-d" 'fortran-join-line) |
| 408 | (define-key fortran-mode-map "\C-xnd" 'fortran-narrow-to-subprogram) | 406 | (define-key fortran-mode-map "\C-xnd" 'fortran-narrow-to-subprogram) |
| 409 | (define-key fortran-mode-map "\t" 'fortran-indent-line) | 407 | ;(define-key fortran-mode-map "\t" 'fortran-indent-line) |
| 410 | (define-key fortran-mode-map "0" 'fortran-electric-line-number) | 408 | (define-key fortran-mode-map "0" 'fortran-electric-line-number) |
| 411 | (define-key fortran-mode-map "1" 'fortran-electric-line-number) | 409 | (define-key fortran-mode-map "1" 'fortran-electric-line-number) |
| 412 | (define-key fortran-mode-map "2" 'fortran-electric-line-number) | 410 | (define-key fortran-mode-map "2" 'fortran-electric-line-number) |
| @@ -452,6 +450,7 @@ subroutine\\|entry\\|block\\s-*data\\|program\\)[ \t" fortran-continuation-strin | |||
| 452 | "----" | 450 | "----" |
| 453 | ["Break Line at Point" fortran-split-line t] | 451 | ["Break Line at Point" fortran-split-line t] |
| 454 | ["Join Continuation Line" fortran-join-line t] | 452 | ["Join Continuation Line" fortran-join-line t] |
| 453 | ["Fill Statement/Comment" fill-paragraph t] | ||
| 455 | "----" | 454 | "----" |
| 456 | ["Add imenu menu" | 455 | ["Add imenu menu" |
| 457 | (progn (imenu-add-to-menubar "Index") | 456 | (progn (imenu-add-to-menubar "Index") |
| @@ -524,7 +523,9 @@ subroutine\\|entry\\|block\\s-*data\\|program\\)[ \t" fortran-continuation-strin | |||
| 524 | (define-abbrev fortran-mode-abbrev-table ";wh" "where" nil) | 523 | (define-abbrev fortran-mode-abbrev-table ";wh" "where" nil) |
| 525 | (setq abbrevs-changed ac))) | 524 | (setq abbrevs-changed ac))) |
| 526 | 525 | ||
| 527 | (eval-when-compile (defvar imenu-syntax-alist nil)) ; silence compiler | 526 | (eval-when-compile ; silence compiler |
| 527 | (defvar imenu-case-fold-search) | ||
| 528 | (defvar imenu-syntax-alist)) | ||
| 528 | 529 | ||
| 529 | ;;;###autoload | 530 | ;;;###autoload |
| 530 | (defun fortran-mode () | 531 | (defun fortran-mode () |
| @@ -532,8 +533,8 @@ subroutine\\|entry\\|block\\s-*data\\|program\\)[ \t" fortran-continuation-strin | |||
| 532 | \\[fortran-indent-line] indents the current Fortran line correctly. | 533 | \\[fortran-indent-line] indents the current Fortran line correctly. |
| 533 | DO statements must not share a common CONTINUE. | 534 | DO statements must not share a common CONTINUE. |
| 534 | 535 | ||
| 535 | Type ;? or ;\\[help-command] to display a list of built-in\ | 536 | Type ;? or ;\\[help-command] to display a list of built-in abbrevs for |
| 536 | abbrevs for Fortran keywords. | 537 | Fortran keywords. |
| 537 | 538 | ||
| 538 | Key definitions: | 539 | Key definitions: |
| 539 | \\{fortran-mode-map} | 540 | \\{fortran-mode-map} |
| @@ -591,7 +592,7 @@ Variables controlling indentation style and extra features: | |||
| 591 | Non-nil causes line number digits to be moved to the correct column | 592 | Non-nil causes line number digits to be moved to the correct column |
| 592 | as typed. (default t) | 593 | as typed. (default t) |
| 593 | fortran-break-before-delimiters | 594 | fortran-break-before-delimiters |
| 594 | Non-nil causes `fortran-fill' breaks lines before delimiters. | 595 | Non-nil causes `fortran-fill' to break lines before delimiters. |
| 595 | (default t) | 596 | (default t) |
| 596 | 597 | ||
| 597 | Turning on Fortran mode calls the value of the variable `fortran-mode-hook' | 598 | Turning on Fortran mode calls the value of the variable `fortran-mode-hook' |
| @@ -629,23 +630,28 @@ with no args, if that value is non-nil." | |||
| 629 | (make-local-variable 'indent-tabs-mode) | 630 | (make-local-variable 'indent-tabs-mode) |
| 630 | (setq indent-tabs-mode nil) | 631 | (setq indent-tabs-mode nil) |
| 631 | ;;;(setq abbrev-mode t) ; ?? (abbrev-mode 1) instead?? | 632 | ;;;(setq abbrev-mode t) ; ?? (abbrev-mode 1) instead?? |
| 632 | (setq fill-column 72) ; Already local? | 633 | (set (make-local-variable 'fill-column) 72) |
| 633 | (use-local-map fortran-mode-map) | 634 | (use-local-map fortran-mode-map) |
| 634 | (setq mode-name "Fortran") | 635 | (setq mode-name "Fortran") |
| 635 | (setq major-mode 'fortran-mode) | 636 | (setq major-mode 'fortran-mode) |
| 636 | ;;;(make-local-variable 'fortran-tab-mode) | ||
| 637 | (make-local-variable 'fortran-comment-line-extra-indent) | 637 | (make-local-variable 'fortran-comment-line-extra-indent) |
| 638 | (make-local-variable 'fortran-minimum-statement-indent-fixed) | 638 | (make-local-variable 'fortran-minimum-statement-indent-fixed) |
| 639 | (make-local-variable 'fortran-minimum-statement-indent-tab) | 639 | (make-local-variable 'fortran-minimum-statement-indent-tab) |
| 640 | (make-local-variable 'fortran-column-ruler-fixed) | 640 | (make-local-variable 'fortran-column-ruler-fixed) |
| 641 | (make-local-variable 'fortran-column-ruler-tab) | 641 | (make-local-variable 'fortran-column-ruler-tab) |
| 642 | (make-local-variable 'fortran-tab-mode-string) | ||
| 643 | (setq fortran-tab-mode-string " TAB-format") | 642 | (setq fortran-tab-mode-string " TAB-format") |
| 644 | (setq indent-tabs-mode (fortran-analyze-file-format)) | 643 | (setq indent-tabs-mode (fortran-analyze-file-format)) |
| 645 | (setq imenu-case-fold-search t) | 644 | (setq imenu-case-fold-search t) |
| 646 | (make-local-variable 'imenu-generic-expression) | 645 | (make-local-variable 'imenu-generic-expression) |
| 647 | (setq imenu-generic-expression fortran-imenu-generic-expression) | 646 | (setq imenu-generic-expression fortran-imenu-generic-expression) |
| 648 | (setq imenu-syntax-alist '(("_$" . "w"))) | 647 | (setq imenu-syntax-alist '(("_$" . "w"))) |
| 648 | (set (make-local-variable 'fill-paragraph-function) 'fortran-fill-paragraph) | ||
| 649 | (set (make-local-variable 'indent-line-function) 'fortran-indent-line) | ||
| 650 | (set (make-local-variable 'indent-region-function) | ||
| 651 | (lambda (start end) | ||
| 652 | (let (fortran-blink-matching-if ; avoid blinking delay | ||
| 653 | indent-region-function) | ||
| 654 | (indent-region start end nil)))) | ||
| 649 | (run-hooks 'fortran-mode-hook)) | 655 | (run-hooks 'fortran-mode-hook)) |
| 650 | 656 | ||
| 651 | (defun fortran-comment-hook () | 657 | (defun fortran-comment-hook () |
| @@ -693,7 +699,7 @@ or on a new line inserted before this line if this line is not blank." | |||
| 693 | (insert-char (if (stringp fortran-comment-indent-char) | 699 | (insert-char (if (stringp fortran-comment-indent-char) |
| 694 | (aref fortran-comment-indent-char 0) | 700 | (aref fortran-comment-indent-char 0) |
| 695 | fortran-comment-indent-char) | 701 | fortran-comment-indent-char) |
| 696 | (- (calculate-fortran-indent) (current-column)))))) | 702 | (- (fortran-calculate-indent) (current-column)))))) |
| 697 | 703 | ||
| 698 | (defun fortran-comment-region (beg-region end-region arg) | 704 | (defun fortran-comment-region (beg-region end-region arg) |
| 699 | "Comments every line in the region. | 705 | "Comments every line in the region. |
| @@ -806,26 +812,23 @@ See also `fortran-window-create'." | |||
| 806 | (if (save-excursion (beginning-of-line) (looking-at comment-line-start-skip)) | 812 | (if (save-excursion (beginning-of-line) (looking-at comment-line-start-skip)) |
| 807 | (insert "\n" comment-line-start " ") | 813 | (insert "\n" comment-line-start " ") |
| 808 | (if indent-tabs-mode | 814 | (if indent-tabs-mode |
| 809 | (progn | 815 | (insert "\n\t" (fortran-numerical-continuation-char)) |
| 810 | (insert "\n\t") | 816 | (insert "\n " fortran-continuation-string))) ; Space after \n important |
| 811 | (insert-char (fortran-numerical-continuation-char) 1)) | 817 | (fortran-indent-line)) ; when the cont string is C, c or *. |
| 812 | (insert "\n " fortran-continuation-string)));Space after \n important | 818 | |
| 813 | (fortran-indent-line)) ;when the cont string is C, c or *. | 819 | (defun fortran-remove-continuation () |
| 820 | (if (looking-at "\\( [^ 0\n]\\|\t[1-9]\\|&\\)") | ||
| 821 | (progn (replace-match "") | ||
| 822 | (delete-indentation) | ||
| 823 | t))) | ||
| 814 | 824 | ||
| 815 | (defun fortran-join-line () | 825 | (defun fortran-join-line () |
| 816 | "Join a continuation line to the previous one and re-indent." | 826 | "Join a continuation line to the previous one and re-indent." |
| 817 | (interactive) | 827 | (interactive) |
| 818 | (save-excursion | 828 | (save-excursion |
| 819 | (beginning-of-line) | 829 | (beginning-of-line) |
| 820 | (cond ((looking-at " \\S-") | 830 | (if (not (fortran-remove-continuation)) |
| 821 | (delete-region (1- (point)) (+ (point) 7))) | 831 | (error "Not a continuation line")) |
| 822 | ((looking-at "&") | ||
| 823 | (delete-region (1- (point)) (1+ (point)))) | ||
| 824 | ((looking-at " *\t[1-9]") | ||
| 825 | (apply 'delete-region (match-data)) | ||
| 826 | (delete-backward-char 1)) | ||
| 827 | (t (error "This isn't a continuation line"))) | ||
| 828 | (just-one-space) | ||
| 829 | (fortran-indent-line))) | 832 | (fortran-indent-line))) |
| 830 | 833 | ||
| 831 | (defun fortran-numerical-continuation-char () | 834 | (defun fortran-numerical-continuation-char () |
| @@ -859,8 +862,8 @@ Auto-indent does not happen if a numeric ARG is used." | |||
| 859 | (beginning-of-line) | 862 | (beginning-of-line) |
| 860 | (looking-at " ")));In col 5 with only spaces to left. | 863 | (looking-at " ")));In col 5 with only spaces to left. |
| 861 | (and (= (if indent-tabs-mode | 864 | (and (= (if indent-tabs-mode |
| 862 | fortran-minimum-statement-indent-tab | 865 | fortran-minimum-statement-indent-tab |
| 863 | fortran-minimum-statement-indent-fixed) (current-column)) | 866 | fortran-minimum-statement-indent-fixed) (current-column)) |
| 864 | (save-excursion | 867 | (save-excursion |
| 865 | (beginning-of-line) | 868 | (beginning-of-line) |
| 866 | (looking-at "\t"));In col 8 with a single tab to the left. | 869 | (looking-at "\t"));In col 8 with a single tab to the left. |
| @@ -872,31 +875,34 @@ Auto-indent does not happen if a numeric ARG is used." | |||
| 872 | (save-excursion | 875 | (save-excursion |
| 873 | (beginning-of-line) | 876 | (beginning-of-line) |
| 874 | (point)) | 877 | (point)) |
| 875 | t)) ;not a line number | 878 | t)) ;not a line number |
| 876 | (looking-at "[0-9]") ;within a line number | 879 | (looking-at "[0-9]")) ;within a line number |
| 877 | ) | ||
| 878 | (self-insert-command (prefix-numeric-value arg)) | 880 | (self-insert-command (prefix-numeric-value arg)) |
| 879 | (skip-chars-backward " \t") | 881 | (skip-chars-backward " \t") |
| 880 | (insert last-command-char) | 882 | (insert last-command-char) |
| 881 | (fortran-indent-line)))) | 883 | (fortran-indent-line)))) |
| 882 | 884 | ||
| 885 | (defvar fortran-end-prog-re1 | ||
| 886 | "end\\b[ \t]*\\(\\(program\\|subroutine\\|function\\)[ \t]*\\)?[^ \t=\(a-z]") | ||
| 887 | (defvar fortran-end-prog-re | ||
| 888 | (concat "^[ \t0-9]*" fortran-end-prog-re1)) | ||
| 889 | |||
| 883 | (defun beginning-of-fortran-subprogram () | 890 | (defun beginning-of-fortran-subprogram () |
| 884 | "Moves point to the beginning of the current Fortran subprogram." | 891 | "Moves point to the beginning of the current Fortran subprogram." |
| 885 | (interactive) | 892 | (interactive) |
| 886 | (let ((case-fold-search t)) | 893 | (let ((case-fold-search t)) |
| 887 | (beginning-of-line -1) | 894 | (beginning-of-line -1) |
| 888 | (re-search-backward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move) | 895 | (if (re-search-backward fortran-end-prog-re nil 'move) |
| 889 | (if (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]") | 896 | (forward-line)))) |
| 890 | (forward-line 1)))) | ||
| 891 | 897 | ||
| 892 | (defun end-of-fortran-subprogram () | 898 | (defun end-of-fortran-subprogram () |
| 893 | "Moves point to the end of the current Fortran subprogram." | 899 | "Moves point to the end of the current Fortran subprogram." |
| 894 | (interactive) | 900 | (interactive) |
| 895 | (let ((case-fold-search t)) | 901 | (let ((case-fold-search t)) |
| 896 | (beginning-of-line 2) | 902 | (beginning-of-line 2) |
| 897 | (re-search-forward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move) | 903 | (re-search-forward fortran-end-prog-re nil 'move) |
| 898 | (goto-char (match-beginning 0)) | 904 | (goto-char (match-beginning 0)) |
| 899 | (forward-line 1))) | 905 | (forward-line))) |
| 900 | 906 | ||
| 901 | (defun mark-fortran-subprogram () | 907 | (defun mark-fortran-subprogram () |
| 902 | "Put mark at end of Fortran subprogram, point at beginning. | 908 | "Put mark at end of Fortran subprogram, point at beginning. |
| @@ -963,8 +969,11 @@ The subprogram visible is the one that contains or follows point." | |||
| 963 | 969 | ||
| 964 | (defun fortran-blink-matching-if () | 970 | (defun fortran-blink-matching-if () |
| 965 | ;; From a Fortran ENDIF statement, blink the matching IF statement. | 971 | ;; From a Fortran ENDIF statement, blink the matching IF statement. |
| 966 | (let ((top-of-window (window-start)) matching-if | 972 | (let ((top-of-window (window-start)) |
| 967 | (endif-point (point)) message) | 973 | (endif-point (point)) |
| 974 | (case-fold-search t) | ||
| 975 | matching-if | ||
| 976 | message) | ||
| 968 | (if (save-excursion (beginning-of-line) | 977 | (if (save-excursion (beginning-of-line) |
| 969 | (skip-chars-forward " \t0-9") | 978 | (skip-chars-forward " \t0-9") |
| 970 | (looking-at "end[ \t]*if\\b")) | 979 | (looking-at "end[ \t]*if\\b")) |
| @@ -988,8 +997,11 @@ The subprogram visible is the one that contains or follows point." | |||
| 988 | (defun fortran-blink-matching-do () | 997 | (defun fortran-blink-matching-do () |
| 989 | ;; From a Fortran ENDDO statement, blink on the matching DO or DO WHILE | 998 | ;; From a Fortran ENDDO statement, blink on the matching DO or DO WHILE |
| 990 | ;; statement. This is basically copied from fortran-blink-matching-if. | 999 | ;; statement. This is basically copied from fortran-blink-matching-if. |
| 991 | (let ((top-of-window (window-start)) matching-do | 1000 | (let ((top-of-window (window-start)) |
| 992 | (enddo-point (point)) message) | 1001 | (enddo-point (point)) |
| 1002 | (case-fold-search t) | ||
| 1003 | matching-do | ||
| 1004 | message) | ||
| 993 | (if (save-excursion (beginning-of-line) | 1005 | (if (save-excursion (beginning-of-line) |
| 994 | (skip-chars-forward " \t0-9") | 1006 | (skip-chars-forward " \t0-9") |
| 995 | (looking-at "end[ \t]*do\\b")) | 1007 | (looking-at "end[ \t]*do\\b")) |
| @@ -1025,52 +1037,54 @@ The marks are pushed." | |||
| 1025 | 1037 | ||
| 1026 | (defun fortran-end-do () | 1038 | (defun fortran-end-do () |
| 1027 | ;; Search forward for first unmatched ENDDO. Return point or nil. | 1039 | ;; Search forward for first unmatched ENDDO. Return point or nil. |
| 1028 | (if (save-excursion (beginning-of-line) | 1040 | (let ((case-fold-search t)) |
| 1029 | (skip-chars-forward " \t0-9") | 1041 | (if (save-excursion (beginning-of-line) |
| 1030 | (looking-at "end[ \t]*do\\b")) | 1042 | (skip-chars-forward " \t0-9") |
| 1031 | ;; Sitting on one. | 1043 | (looking-at "end[ \t]*do\\b")) |
| 1032 | (match-beginning 0) | 1044 | ;; Sitting on one. |
| 1033 | ;; Search for one. | 1045 | (match-beginning 0) |
| 1034 | (save-excursion | 1046 | ;; Search for one. |
| 1035 | (let ((count 1)) | 1047 | (save-excursion |
| 1048 | (let ((count 1)) | ||
| 1036 | (while (and (not (= count 0)) | 1049 | (while (and (not (= count 0)) |
| 1037 | (not (eq (fortran-next-statement) 'last-statement)) | 1050 | (not (eq (fortran-next-statement) 'last-statement)) |
| 1038 | ;; Keep local to subprogram | 1051 | ;; Keep local to subprogram |
| 1039 | (not (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) | 1052 | (not (looking-at fortran-end-prog-re))) |
| 1040 | 1053 | ||
| 1041 | (skip-chars-forward " \t0-9") | 1054 | (skip-chars-forward " \t0-9") |
| 1042 | (cond ((looking-at "end[ \t]*do\\b") | 1055 | (cond ((looking-at "end[ \t]*do\\b") |
| 1043 | (setq count (- count 1))) | 1056 | (setq count (1- count))) |
| 1044 | ((looking-at "do[ \t]+[^0-9]") | 1057 | ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]") |
| 1045 | (setq count (+ count 1))))) | 1058 | (setq count (+ count 1))))) |
| 1046 | (and (= count 0) | 1059 | (and (= count 0) |
| 1047 | ;; All pairs accounted for. | 1060 | ;; All pairs accounted for. |
| 1048 | (point)))))) | 1061 | (point))))))) |
| 1049 | 1062 | ||
| 1050 | (defun fortran-beginning-do () | 1063 | (defun fortran-beginning-do () |
| 1051 | ;; Search backwards for first unmatched DO [WHILE]. Return point or nil. | 1064 | ;; Search backwards for first unmatched DO [WHILE]. Return point or nil. |
| 1052 | (if (save-excursion (beginning-of-line) | 1065 | (let ((case-fold-search t)) |
| 1053 | (skip-chars-forward " \t0-9") | 1066 | (if (save-excursion (beginning-of-line) |
| 1054 | (looking-at "do[ \t]+")) | 1067 | (skip-chars-forward " \t0-9") |
| 1055 | ;; Sitting on one. | 1068 | (looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+")) |
| 1056 | (match-beginning 0) | 1069 | ;; Sitting on one. |
| 1057 | ;; Search for one. | 1070 | (match-beginning 0) |
| 1058 | (save-excursion | 1071 | ;; Search for one. |
| 1059 | (let ((count 1)) | 1072 | (save-excursion |
| 1073 | (let ((count 1)) | ||
| 1060 | (while (and (not (= count 0)) | 1074 | (while (and (not (= count 0)) |
| 1061 | (not (eq (fortran-previous-statement) 'first-statement)) | 1075 | (not (eq (fortran-previous-statement) 'first-statement)) |
| 1062 | ;; Keep local to subprogram | 1076 | ;; Keep local to subprogram |
| 1063 | (not (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) | 1077 | (not (looking-at fortran-end-prog-re))) |
| 1064 | 1078 | ||
| 1065 | (skip-chars-forward " \t0-9") | 1079 | (skip-chars-forward " \t0-9") |
| 1066 | (cond ((looking-at "do[ \t]+[^0-9]") | 1080 | (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?do[ \t]+[^0-9]") |
| 1067 | (setq count (- count 1))) | 1081 | (setq count (1- count))) |
| 1068 | ((looking-at "end[ \t]*do\\b") | 1082 | ((looking-at "end[ \t]*do\\b") |
| 1069 | (setq count (+ count 1))))) | 1083 | (setq count (1+ count))))) |
| 1070 | 1084 | ||
| 1071 | (and (= count 0) | 1085 | (and (= count 0) |
| 1072 | ;; All pairs accounted for. | 1086 | ;; All pairs accounted for. |
| 1073 | (point)))))) | 1087 | (point))))))) |
| 1074 | 1088 | ||
| 1075 | (defun fortran-mark-if () | 1089 | (defun fortran-mark-if () |
| 1076 | "Put mark at end of Fortran IF-ENDIF construct, point at beginning. | 1090 | "Put mark at end of Fortran IF-ENDIF construct, point at beginning. |
| @@ -1085,113 +1099,115 @@ The marks are pushed." | |||
| 1085 | (push-mark) | 1099 | (push-mark) |
| 1086 | (goto-char if-point))))) | 1100 | (goto-char if-point))))) |
| 1087 | 1101 | ||
| 1102 | (defvar fortran-if-start-re "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(") | ||
| 1103 | |||
| 1088 | (defun fortran-end-if () | 1104 | (defun fortran-end-if () |
| 1089 | ;; Search forwards for first unmatched ENDIF. Return point or nil. | 1105 | ;; Search forwards for first unmatched ENDIF. Return point or nil. |
| 1090 | (if (save-excursion (beginning-of-line) | 1106 | (let ((case-fold-search t)) |
| 1091 | (skip-chars-forward " \t0-9") | 1107 | (if (save-excursion (beginning-of-line) |
| 1092 | (looking-at "end[ \t]*if\\b")) | 1108 | (skip-chars-forward " \t0-9") |
| 1093 | ;; Sitting on one. | 1109 | (looking-at "end[ \t]*if\\b")) |
| 1094 | (match-beginning 0) | 1110 | ;; Sitting on one. |
| 1095 | ;; Search for one. The point has been already been moved to first | 1111 | (match-beginning 0) |
| 1096 | ;; letter on line but this should not cause troubles. | 1112 | ;; Search for one. The point has been already been moved to first |
| 1097 | (save-excursion | 1113 | ;; letter on line but this should not cause troubles. |
| 1098 | (let ((count 1)) | 1114 | (save-excursion |
| 1115 | (let ((count 1)) | ||
| 1099 | (while (and (not (= count 0)) | 1116 | (while (and (not (= count 0)) |
| 1100 | (not (eq (fortran-next-statement) 'last-statement)) | 1117 | (not (eq (fortran-next-statement) 'last-statement)) |
| 1101 | ;; Keep local to subprogram. | 1118 | ;; Keep local to subprogram. |
| 1102 | (not (looking-at | 1119 | (not (looking-at fortran-end-prog-re))) |
| 1103 | "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) | ||
| 1104 | 1120 | ||
| 1105 | (skip-chars-forward " \t0-9") | 1121 | (skip-chars-forward " \t0-9") |
| 1106 | (cond ((looking-at "end[ \t]*if\\b") | 1122 | (cond ((looking-at "end[ \t]*if\\b") |
| 1107 | (setq count (- count 1))) | 1123 | (setq count (- count 1))) |
| 1108 | 1124 | ||
| 1109 | ((looking-at "if[ \t]*(") | 1125 | ((looking-at fortran-if-start-re) |
| 1110 | (save-excursion | 1126 | (save-excursion |
| 1111 | (if (or | 1127 | (if (or |
| 1112 | (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") | 1128 | (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") |
| 1113 | (let (then-test) ; Multi-line if-then. | 1129 | (let (then-test) ; Multi-line if-then. |
| 1114 | (while | 1130 | (while |
| 1115 | (and (= (forward-line 1) 0) | 1131 | (and (= (forward-line 1) 0) |
| 1116 | ;; Search forward for then. | 1132 | ;; Search forward for then. |
| 1117 | (or (looking-at " [^ 0\n]") | 1133 | (or (looking-at " [^ 0\n]") |
| 1118 | (looking-at "\t[1-9]")) | 1134 | (looking-at "\t[1-9]")) |
| 1119 | (not | 1135 | (not |
| 1120 | (setq then-test | 1136 | (setq then-test |
| 1121 | (looking-at | 1137 | (looking-at |
| 1122 | ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) | 1138 | ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) |
| 1123 | then-test)) | 1139 | then-test)) |
| 1124 | (setq count (+ count 1))))))) | 1140 | (setq count (+ count 1))))))) |
| 1125 | 1141 | ||
| 1126 | (and (= count 0) | 1142 | (and (= count 0) |
| 1127 | ;; All pairs accounted for. | 1143 | ;; All pairs accounted for. |
| 1128 | (point)))))) | 1144 | (point))))))) |
| 1129 | 1145 | ||
| 1130 | (defun fortran-beginning-if () | 1146 | (defun fortran-beginning-if () |
| 1131 | ;; Search backwards for first unmatched IF-THEN. Return point or nil. | 1147 | ;; Search backwards for first unmatched IF-THEN. Return point or nil. |
| 1132 | (if (save-excursion | 1148 | (let ((case-fold-search t)) |
| 1133 | ;; May be sitting on multi-line if-then statement, first move to | 1149 | (if (save-excursion |
| 1134 | ;; beginning of current statement. Note: `fortran-previous-statement' | 1150 | ;; May be sitting on multi-line if-then statement, first move to |
| 1135 | ;; moves to previous statement *unless* current statement is first | 1151 | ;; beginning of current statement. Note: `fortran-previous-statement' |
| 1136 | ;; one. Only move forward if not first-statement. | 1152 | ;; moves to previous statement *unless* current statement is first |
| 1137 | (if (not (eq (fortran-previous-statement) 'first-statement)) | 1153 | ;; one. Only move forward if not first-statement. |
| 1138 | (fortran-next-statement)) | 1154 | (if (not (eq (fortran-previous-statement) 'first-statement)) |
| 1139 | (skip-chars-forward " \t0-9") | 1155 | (fortran-next-statement)) |
| 1140 | (and | 1156 | (skip-chars-forward " \t0-9") |
| 1141 | (looking-at "if[ \t]*(") | 1157 | (and |
| 1142 | (save-match-data | 1158 | (looking-at fortran-if-start-re) |
| 1143 | (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") | 1159 | (save-match-data |
| 1144 | ;; Multi-line if-then. | 1160 | (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") |
| 1145 | (let (then-test) | 1161 | ;; Multi-line if-then. |
| 1146 | (while | 1162 | (let (then-test) |
| 1163 | (while | ||
| 1147 | (and (= (forward-line 1) 0) | 1164 | (and (= (forward-line 1) 0) |
| 1148 | ;; Search forward for then. | 1165 | ;; Search forward for then. |
| 1149 | (or (looking-at " [^ 0\n]") | 1166 | (or (looking-at " [^ 0\n]") |
| 1150 | (looking-at "\t[1-9]")) | 1167 | (looking-at "\t[1-9]")) |
| 1151 | (not | 1168 | (not |
| 1152 | (setq then-test | 1169 | (setq then-test |
| 1153 | (looking-at | 1170 | (looking-at |
| 1154 | ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) | 1171 | ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) |
| 1155 | then-test))))) | 1172 | then-test))))) |
| 1156 | ;; Sitting on one. | 1173 | ;; Sitting on one. |
| 1157 | (match-beginning 0) | 1174 | (match-beginning 0) |
| 1158 | ;; Search for one. | 1175 | ;; Search for one. |
| 1159 | (save-excursion | 1176 | (save-excursion |
| 1160 | (let ((count 1)) | 1177 | (let ((count 1)) |
| 1161 | (while (and (not (= count 0)) | 1178 | (while (and (not (= count 0)) |
| 1162 | (not (eq (fortran-previous-statement) 'first-statement)) | 1179 | (not (eq (fortran-previous-statement) 'first-statement)) |
| 1163 | ;; Keep local to subprogram. | 1180 | ;; Keep local to subprogram. |
| 1164 | (not (looking-at | 1181 | (not (looking-at fortran-end-prog-re))) |
| 1165 | "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]"))) | 1182 | |
| 1166 | 1183 | (skip-chars-forward " \t0-9") | |
| 1167 | (skip-chars-forward " \t0-9") | 1184 | (cond ((looking-at fortran-if-start-re) |
| 1168 | (cond ((looking-at "if[ \t]*(") | 1185 | (save-excursion |
| 1169 | (save-excursion | 1186 | (if (or |
| 1170 | (if (or | 1187 | (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") |
| 1171 | (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]") | 1188 | (let (then-test) ; Multi-line if-then. |
| 1172 | (let (then-test) ; Multi-line if-then. | 1189 | (while |
| 1173 | (while | ||
| 1174 | (and (= (forward-line 1) 0) | 1190 | (and (= (forward-line 1) 0) |
| 1175 | ;; Search forward for then. | 1191 | ;; Search forward for then. |
| 1176 | (or (looking-at " [^ 0\n]") | 1192 | (or (looking-at " [^ 0\n]") |
| 1177 | (looking-at "\t[1-9]")) | 1193 | (looking-at "\t[1-9]")) |
| 1178 | (not | 1194 | (not |
| 1179 | (setq then-test | 1195 | (setq then-test |
| 1180 | (looking-at | 1196 | (looking-at |
| 1181 | ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) | 1197 | ".*then\\b[ \t]*[^ \t(=a-z0-9]"))))) |
| 1182 | then-test)) | 1198 | then-test)) |
| 1183 | (setq count (- count 1))))) | 1199 | (setq count (- count 1))))) |
| 1184 | ((looking-at "end[ \t]*if\\b") | 1200 | ((looking-at "end[ \t]*if\\b") |
| 1185 | (setq count (+ count 1))))) | 1201 | (setq count (+ count 1))))) |
| 1186 | 1202 | ||
| 1187 | (and (= count 0) | 1203 | (and (= count 0) |
| 1188 | ;; All pairs accounted for. | 1204 | ;; All pairs accounted for. |
| 1189 | (point)))))) | 1205 | (point))))))) |
| 1190 | 1206 | ||
| 1191 | (defun fortran-indent-line () | 1207 | (defun fortran-indent-line () |
| 1192 | "Indent current Fortran line based on its contents and on previous lines." | 1208 | "Indent current Fortran line based on its contents and on previous lines." |
| 1193 | (interactive) | 1209 | (interactive) |
| 1194 | (let ((cfi (calculate-fortran-indent))) | 1210 | (let ((cfi (fortran-calculate-indent))) |
| 1195 | (save-excursion | 1211 | (save-excursion |
| 1196 | (beginning-of-line) | 1212 | (beginning-of-line) |
| 1197 | (if (or (not (= cfi (fortran-current-line-indentation))) | 1213 | (if (or (not (= cfi (fortran-current-line-indentation))) |
| @@ -1223,11 +1239,12 @@ An abbrev before point is expanded if `abbrev-mode' is non-nil." | |||
| 1223 | (save-excursion | 1239 | (save-excursion |
| 1224 | (beginning-of-line) | 1240 | (beginning-of-line) |
| 1225 | (skip-chars-forward " \t") | 1241 | (skip-chars-forward " \t") |
| 1226 | (if (or (looking-at "[0-9]") ;Reindent only where it is most | 1242 | (let ((case-fold-search t)) |
| 1227 | (looking-at "end") ;likely to be necessary | 1243 | (if (or (looking-at "[0-9]") ;Reindent only where it is most |
| 1228 | (looking-at "else") | 1244 | (looking-at "end") ;likely to be necessary |
| 1229 | (looking-at (regexp-quote fortran-continuation-string))) | 1245 | (looking-at "else") |
| 1230 | (fortran-indent-line))) | 1246 | (looking-at (regexp-quote fortran-continuation-string))) |
| 1247 | (fortran-indent-line)))) | ||
| 1231 | (newline) | 1248 | (newline) |
| 1232 | (fortran-indent-line)) | 1249 | (fortran-indent-line)) |
| 1233 | 1250 | ||
| @@ -1240,7 +1257,7 @@ An abbrev before point is expanded if `abbrev-mode' is non-nil." | |||
| 1240 | (indent-region (point) (mark) nil)) | 1257 | (indent-region (point) (mark) nil)) |
| 1241 | (message "Indenting subprogram...done.")) | 1258 | (message "Indenting subprogram...done.")) |
| 1242 | 1259 | ||
| 1243 | (defun calculate-fortran-indent () | 1260 | (defun fortran-calculate-indent () |
| 1244 | "Calculates the Fortran indent column based on previous lines." | 1261 | "Calculates the Fortran indent column based on previous lines." |
| 1245 | (let (icol first-statement (case-fold-search t) | 1262 | (let (icol first-statement (case-fold-search t) |
| 1246 | (fortran-minimum-statement-indent | 1263 | (fortran-minimum-statement-indent |
| @@ -1256,7 +1273,7 @@ An abbrev before point is expanded if `abbrev-mode' is non-nil." | |||
| 1256 | (setq icol fortran-minimum-statement-indent) | 1273 | (setq icol fortran-minimum-statement-indent) |
| 1257 | (setq icol (fortran-current-line-indentation))) | 1274 | (setq icol (fortran-current-line-indentation))) |
| 1258 | (skip-chars-forward " \t0-9") | 1275 | (skip-chars-forward " \t0-9") |
| 1259 | (cond ((looking-at "if[ \t]*(") | 1276 | (cond ((looking-at "\\(\\(\\sw\\|\\s_\\)+:[ \t]*\\)?if[ \t]*(") |
| 1260 | (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]") | 1277 | (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]") |
| 1261 | (let (then-test) ;multi-line if-then | 1278 | (let (then-test) ;multi-line if-then |
| 1262 | (while (and (= (forward-line 1) 0) | 1279 | (while (and (= (forward-line 1) 0) |
| @@ -1268,11 +1285,11 @@ An abbrev before point is expanded if `abbrev-mode' is non-nil." | |||
| 1268 | *[^ \t_$(=a-z0-9]"))))) | 1285 | *[^ \t_$(=a-z0-9]"))))) |
| 1269 | then-test)) | 1286 | then-test)) |
| 1270 | (setq icol (+ icol fortran-if-indent)))) | 1287 | (setq icol (+ icol fortran-if-indent)))) |
| 1271 | ((looking-at "\\(else\\|elseif\\)\\b") | 1288 | ((looking-at "else\\(if\\)?\\b") |
| 1272 | (setq icol (+ icol fortran-if-indent))) | 1289 | (setq icol (+ icol fortran-if-indent))) |
| 1273 | ((looking-at "select[ \t]*case[ \t](.*)\\b") | 1290 | ((looking-at "select[ \t]*case[ \t](.*)") |
| 1274 | (setq icol (+ icol fortran-if-indent))) | 1291 | (setq icol (+ icol fortran-if-indent))) |
| 1275 | ((looking-at "case[ \t]*(.*)[ \t]*\n") | 1292 | ((looking-at "case[ \t]*(.*)") |
| 1276 | (setq icol (+ icol fortran-if-indent))) | 1293 | (setq icol (+ icol fortran-if-indent))) |
| 1277 | ((looking-at "case[ \t]*default\\b") | 1294 | ((looking-at "case[ \t]*default\\b") |
| 1278 | (setq icol (+ icol fortran-if-indent))) | 1295 | (setq icol (+ icol fortran-if-indent))) |
| @@ -1285,7 +1302,7 @@ An abbrev before point is expanded if `abbrev-mode' is non-nil." | |||
| 1285 | ((looking-at | 1302 | ((looking-at |
| 1286 | "\\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]") | 1303 | "\\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]") |
| 1287 | (setq icol (+ icol fortran-structure-indent))) | 1304 | (setq icol (+ icol fortran-structure-indent))) |
| 1288 | ((looking-at "end\\b[ \t]*[^ \t=(a-z]") | 1305 | ((looking-at fortran-end-prog-re1) |
| 1289 | ;; Previous END resets indent to minimum | 1306 | ;; Previous END resets indent to minimum |
| 1290 | (setq icol fortran-minimum-statement-indent)))))) | 1307 | (setq icol fortran-minimum-statement-indent)))))) |
| 1291 | (save-excursion | 1308 | (save-excursion |
| @@ -1313,31 +1330,23 @@ An abbrev before point is expanded if `abbrev-mode' is non-nil." | |||
| 1313 | (setq icol (- icol fortran-do-indent))) | 1330 | (setq icol (- icol fortran-do-indent))) |
| 1314 | (t | 1331 | (t |
| 1315 | (skip-chars-forward " \t0-9") | 1332 | (skip-chars-forward " \t0-9") |
| 1316 | (cond ((looking-at "end[ \t]*if\\b") | 1333 | (cond ((looking-at "end[ \t]*\\(if\\|select\\|where\\)\\b") |
| 1317 | (setq icol (- icol fortran-if-indent))) | ||
| 1318 | ((looking-at "\\(else\\|elseif\\)\\b") | ||
| 1319 | (setq icol (- icol fortran-if-indent))) | 1334 | (setq icol (- icol fortran-if-indent))) |
| 1320 | ((looking-at "case[ \t]*(.*)[ \t]*\n") | 1335 | ((looking-at "else\\(if\\)?\\b") |
| 1321 | (setq icol (- icol fortran-if-indent))) | 1336 | (setq icol (- icol fortran-if-indent))) |
| 1322 | ((looking-at "case[ \t]*default\\b") | 1337 | ((looking-at "case[ \t]*\\((.*)\\|default\\>\\)") |
| 1323 | (setq icol (- icol fortran-if-indent))) | 1338 | (setq icol (- icol fortran-if-indent))) |
| 1324 | ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b") | 1339 | ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b") |
| 1325 | (setq icol (- icol fortran-if-indent))) | 1340 | (setq icol (- icol fortran-if-indent))) |
| 1326 | ((looking-at "end[ \t]*where\\b") | ||
| 1327 | (setq icol (- icol fortran-if-indent))) | ||
| 1328 | ((and (looking-at "continue\\b") | 1341 | ((and (looking-at "continue\\b") |
| 1329 | (fortran-check-for-matching-do)) | 1342 | (fortran-check-for-matching-do)) |
| 1330 | (setq icol (- icol fortran-do-indent))) | 1343 | (setq icol (- icol fortran-do-indent))) |
| 1331 | ((looking-at "end[ \t]*do\\b") | 1344 | ((looking-at "end[ \t]*do\\b") |
| 1332 | (setq icol (- icol fortran-do-indent))) | 1345 | (setq icol (- icol fortran-do-indent))) |
| 1333 | ((looking-at | 1346 | ((looking-at "end[ \t]*\ |
| 1334 | "end[ \t]*\ | ||
| 1335 | \\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]") | 1347 | \\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]") |
| 1336 | (setq icol (- icol fortran-structure-indent))) | 1348 | (setq icol (- icol fortran-structure-indent))) |
| 1337 | ((looking-at | 1349 | ((and (looking-at fortran-end-prog-re1) |
| 1338 | "end[ \t]*select\\b[ \t]*[^ \t=(a-z]") | ||
| 1339 | (setq icol (- icol fortran-if-indent))) | ||
| 1340 | ((and (looking-at "end\\b[ \t]*[^ \t=(a-z]") | ||
| 1341 | (not (= icol fortran-minimum-statement-indent))) | 1350 | (not (= icol fortran-minimum-statement-indent))) |
| 1342 | (message "Warning: `end' not in column %d. Probably\ | 1351 | (message "Warning: `end' not in column %d. Probably\ |
| 1343 | an unclosed block." fortran-minimum-statement-indent)))))) | 1352 | an unclosed block." fortran-minimum-statement-indent)))))) |
| @@ -1459,7 +1468,7 @@ Otherwise return nil." | |||
| 1459 | (point)))) | 1468 | (point)))) |
| 1460 | (beginning-of-line) | 1469 | (beginning-of-line) |
| 1461 | (and (re-search-backward | 1470 | (and (re-search-backward |
| 1462 | (concat "\\(^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]\\)\\|" | 1471 | (concat "\\(" fortran-end-prog-re "\\)\\|" |
| 1463 | "\\(^[ \t0-9]*do[ \t]*0*" charnum "\\b\\)\\|" | 1472 | "\\(^[ \t0-9]*do[ \t]*0*" charnum "\\b\\)\\|" |
| 1464 | "\\(^[ \t]*0*" charnum "\\b\\)") | 1473 | "\\(^[ \t]*0*" charnum "\\b\\)") |
| 1465 | nil t) | 1474 | nil t) |
| @@ -1468,10 +1477,10 @@ Otherwise return nil." | |||
| 1468 | (defun fortran-find-comment-start-skip () | 1477 | (defun fortran-find-comment-start-skip () |
| 1469 | "Move to past `comment-start-skip' found on current line. | 1478 | "Move to past `comment-start-skip' found on current line. |
| 1470 | Return t if `comment-start-skip' found, nil if not." | 1479 | Return t if `comment-start-skip' found, nil if not." |
| 1471 | ;;; In order to move point only if comment-start-skip is found, | 1480 | ;; In order to move point only if comment-start-skip is found, this |
| 1472 | ;;; this one uses a lot of save-excursions. Note that re-search-forward | 1481 | ;; one uses a lot of save-excursions. Note that re-search-forward |
| 1473 | ;;; moves point even if comment-start-skip is inside a string-constant. | 1482 | ;; moves point even if comment-start-skip is inside a string-constant. |
| 1474 | ;;; Some code expects certain values for match-beginning and end | 1483 | ;; Some code expects certain values for match-beginning and end |
| 1475 | (interactive) | 1484 | (interactive) |
| 1476 | (if (save-excursion | 1485 | (if (save-excursion |
| 1477 | (re-search-forward comment-start-skip | 1486 | (re-search-forward comment-start-skip |
| @@ -1489,8 +1498,8 @@ Return t if `comment-start-skip' found, nil if not." | |||
| 1489 | t)) | 1498 | t)) |
| 1490 | nil)) | 1499 | nil)) |
| 1491 | 1500 | ||
| 1492 | ;;;From: simon@gnu (Simon Marshall) | 1501 | ;;From: simon@gnu (Simon Marshall) |
| 1493 | ;;; Find the next ! not in a string. | 1502 | ;; Find the next ! not in a string. |
| 1494 | (defun fortran-match-!-comment (limit) | 1503 | (defun fortran-match-!-comment (limit) |
| 1495 | (let (found) | 1504 | (let (found) |
| 1496 | (while (and (setq found (search-forward "!" limit t)) | 1505 | (while (and (setq found (search-forward "!" limit t)) |
| @@ -1509,8 +1518,8 @@ Return t if `comment-start-skip' found, nil if not." | |||
| 1509 | ;; (fortran-is-in-string-p (match-beginning 0)))) | 1518 | ;; (fortran-is-in-string-p (match-beginning 0)))) |
| 1510 | ;; found)) | 1519 | ;; found)) |
| 1511 | 1520 | ||
| 1512 | ;;;From: ralf@up3aud1.gwdg.de (Ralf Fassel) | 1521 | ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel) |
| 1513 | ;;; Test if TAB format continuation lines work. | 1522 | ;; Test if TAB format continuation lines work. |
| 1514 | (defun fortran-is-in-string-p (where) | 1523 | (defun fortran-is-in-string-p (where) |
| 1515 | "Return non-nil iff WHERE (a buffer position) is inside a Fortran string." | 1524 | "Return non-nil iff WHERE (a buffer position) is inside a Fortran string." |
| 1516 | (save-excursion | 1525 | (save-excursion |
| @@ -1518,7 +1527,8 @@ Return t if `comment-start-skip' found, nil if not." | |||
| 1518 | (cond | 1527 | (cond |
| 1519 | ((bolp) nil) ; bol is never inside a string | 1528 | ((bolp) nil) ; bol is never inside a string |
| 1520 | ((save-excursion ; comment lines too | 1529 | ((save-excursion ; comment lines too |
| 1521 | (beginning-of-line)(looking-at comment-line-start-skip)) nil) | 1530 | (beginning-of-line) |
| 1531 | (looking-at comment-line-start-skip)) nil) | ||
| 1522 | (t (let (;; ok, serious now. Init some local vars: | 1532 | (t (let (;; ok, serious now. Init some local vars: |
| 1523 | (parse-state '(0 nil nil nil nil nil 0)) | 1533 | (parse-state '(0 nil nil nil nil nil 0)) |
| 1524 | (quoted-comment-start (if comment-start | 1534 | (quoted-comment-start (if comment-start |
| @@ -1542,8 +1552,7 @@ Return t if `comment-start-skip' found, nil if not." | |||
| 1542 | comment-start | 1552 | comment-start |
| 1543 | (equal comment-start | 1553 | (equal comment-start |
| 1544 | (char-to-string (preceding-char))))) | 1554 | (char-to-string (preceding-char))))) |
| 1545 | ;; get around a bug in forward-line in versions <= 18.57 | 1555 | (if (> (forward-line) 0) |
| 1546 | (if (or (> (forward-line 1) 0) (eobp)) | ||
| 1547 | (setq not-done nil)) | 1556 | (setq not-done nil)) |
| 1548 | ;; else: | 1557 | ;; else: |
| 1549 | ;; if we are at beginning of code line, skip any | 1558 | ;; if we are at beginning of code line, skip any |
| @@ -1582,7 +1591,7 @@ automatically breaks the line at a previous space." | |||
| 1582 | (if (if (null arg) | 1591 | (if (if (null arg) |
| 1583 | (not auto-fill-function) | 1592 | (not auto-fill-function) |
| 1584 | (> (prefix-numeric-value arg) 0)) | 1593 | (> (prefix-numeric-value arg) 0)) |
| 1585 | 'fortran-do-auto-fill | 1594 | #'fortran-do-auto-fill |
| 1586 | nil)) | 1595 | nil)) |
| 1587 | (force-mode-line-update))) | 1596 | (force-mode-line-update))) |
| 1588 | 1597 | ||
| @@ -1602,19 +1611,16 @@ automatically breaks the line at a previous space." | |||
| 1602 | (if (looking-at comment-line-start-skip) | 1611 | (if (looking-at comment-line-start-skip) |
| 1603 | nil ; OK to break quotes on comment lines. | 1612 | nil ; OK to break quotes on comment lines. |
| 1604 | (move-to-column fill-column) | 1613 | (move-to-column fill-column) |
| 1605 | (cond ((fortran-is-in-string-p (point)) | 1614 | (if (fortran-is-in-string-p (point)) |
| 1606 | (save-excursion (re-search-backward "[^']'[^']" bol t) | 1615 | (save-excursion (re-search-backward "\\S\"\\s\"\\S\"" bol t) |
| 1607 | (if fortran-break-before-delimiters | 1616 | (if fortran-break-before-delimiters |
| 1608 | (point) | 1617 | (point) |
| 1609 | (1+ (point))))) | 1618 | (1+ (point)))))))) |
| 1610 | (t nil))))) | ||
| 1611 | ;; | ||
| 1612 | ;; decide where to split the line. If a position for a quoted | 1619 | ;; decide where to split the line. If a position for a quoted |
| 1613 | ;; string was found above then use that, else break the line | 1620 | ;; string was found above then use that, else break the line |
| 1614 | ;; before the last delimiter. | 1621 | ;; before the last delimiter. |
| 1615 | ;; Delimiters are whitespace, commas, and operators. | 1622 | ;; Delimiters are whitespace, commas, and operators. |
| 1616 | ;; Will break before a pair of *'s. | 1623 | ;; Will break before a pair of *'s. |
| 1617 | ;; | ||
| 1618 | (fill-point | 1624 | (fill-point |
| 1619 | (or quote | 1625 | (or quote |
| 1620 | (save-excursion | 1626 | (save-excursion |
| @@ -1626,19 +1632,18 @@ automatically breaks the line at a previous space." | |||
| 1626 | (if (<= (point) (1+ bos)) | 1632 | (if (<= (point) (1+ bos)) |
| 1627 | (progn | 1633 | (progn |
| 1628 | (move-to-column (1+ fill-column)) | 1634 | (move-to-column (1+ fill-column)) |
| 1629 | ;;;what is this doing??? | 1635 | ;;what is this doing??? |
| 1630 | (if (not (re-search-forward "[\t\n,'+-/*)=]" eol t)) | 1636 | (if (not (re-search-forward "[\t\n,'+-/*)=]" eol t)) |
| 1631 | (goto-char bol)))) | 1637 | (goto-char bol)))) |
| 1632 | (if (bolp) | 1638 | (if (bolp) |
| 1633 | (re-search-forward "[ \t]" opoint t) | 1639 | (re-search-forward "[ \t]" opoint t) |
| 1634 | (forward-char -1) | 1640 | (backward-char) |
| 1635 | (if (looking-at "'") | 1641 | (if (looking-at "\\s\"") |
| 1636 | (forward-char 1) | 1642 | (forward-char) |
| 1637 | (skip-chars-backward " \t\*"))) | 1643 | (skip-chars-backward " \t\*"))) |
| 1638 | (if fortran-break-before-delimiters | 1644 | (if fortran-break-before-delimiters |
| 1639 | (point) | 1645 | (point) |
| 1640 | (1+ (point)))))) | 1646 | (1+ (point))))))) |
| 1641 | ) | ||
| 1642 | ;; if we are in an in-line comment, don't break unless the | 1647 | ;; if we are in an in-line comment, don't break unless the |
| 1643 | ;; line of code is longer than it should be. Otherwise | 1648 | ;; line of code is longer than it should be. Otherwise |
| 1644 | ;; break the line at the column computed above. | 1649 | ;; break the line at the column computed above. |
| @@ -1663,7 +1668,7 @@ automatically breaks the line at a previous space." | |||
| 1663 | (if (> (save-excursion | 1668 | (if (> (save-excursion |
| 1664 | (goto-char fill-point) | 1669 | (goto-char fill-point) |
| 1665 | (current-column)) | 1670 | (current-column)) |
| 1666 | (+ (calculate-fortran-indent) fortran-continuation-indent)) | 1671 | (+ (fortran-calculate-indent) fortran-continuation-indent)) |
| 1667 | (progn | 1672 | (progn |
| 1668 | (goto-char fill-point) | 1673 | (goto-char fill-point) |
| 1669 | (fortran-break-line)))))) | 1674 | (fortran-break-line)))))) |
| @@ -1680,8 +1685,8 @@ automatically breaks the line at a previous space." | |||
| 1680 | (re-search-backward comment-start-skip bol t) | 1685 | (re-search-backward comment-start-skip bol t) |
| 1681 | (setq comment-string (buffer-substring (point) eol)) | 1686 | (setq comment-string (buffer-substring (point) eol)) |
| 1682 | (delete-region (point) eol)))) | 1687 | (delete-region (point) eol)))) |
| 1683 | ;;; Forward line 1 really needs to go to next non white line | 1688 | ;; Forward line 1 really needs to go to next non white line |
| 1684 | (if (save-excursion (forward-line 1) | 1689 | (if (save-excursion (forward-line) |
| 1685 | (or (looking-at " [^ 0\n]") | 1690 | (or (looking-at " [^ 0\n]") |
| 1686 | (looking-at "\t[1-9]"))) | 1691 | (looking-at "\t[1-9]"))) |
| 1687 | (progn | 1692 | (progn |
| @@ -1725,6 +1730,70 @@ file before the end or the first `fortran-analyze-depth' lines." | |||
| 1725 | (indent-tabs-mode fortran-tab-mode-string)) | 1730 | (indent-tabs-mode fortran-tab-mode-string)) |
| 1726 | minor-mode-alist))) | 1731 | minor-mode-alist))) |
| 1727 | 1732 | ||
| 1733 | (defun fortran-fill-paragraph (&optional justify) | ||
| 1734 | "Fill surrounding comment block as paragraphs, else fill statement. | ||
| 1735 | |||
| 1736 | Intended as the value of `fill-paragraph-function'." | ||
| 1737 | (interactive "P") | ||
| 1738 | (save-excursion | ||
| 1739 | (beginning-of-line) | ||
| 1740 | (if (not (looking-at "[Cc*]")) | ||
| 1741 | (fortran-fill-statement) | ||
| 1742 | ;; We're in a comment block. Find the start and end of a | ||
| 1743 | ;; paragraph, delimited either by non-comment lines or empty | ||
| 1744 | ;; comments. (Get positions as markers, since the | ||
| 1745 | ;; `indent-region' below can shift the block's end). | ||
| 1746 | (let* ((non-empty-comment (concat "\\(" comment-line-start-skip | ||
| 1747 | "\\)" "[^ \t\n]")) | ||
| 1748 | (start (save-excursion | ||
| 1749 | ;; Find (start of) first line. | ||
| 1750 | (while (and (zerop (forward-line -1)) | ||
| 1751 | (looking-at non-empty-comment))) | ||
| 1752 | (or (looking-at non-empty-comment) | ||
| 1753 | (forward-line)) ; overshot | ||
| 1754 | (point-marker))) | ||
| 1755 | (end (save-excursion | ||
| 1756 | ;; Find start of first line past region to fill. | ||
| 1757 | (while (progn (forward-line) | ||
| 1758 | (looking-at non-empty-comment))) | ||
| 1759 | (point-marker)))) | ||
| 1760 | ;; Indent the block, find the string comprising the effective | ||
| 1761 | ;; comment start skip and use that as a fill-prefix for | ||
| 1762 | ;; filling the region. | ||
| 1763 | (indent-region start end nil) | ||
| 1764 | (let ((paragraph-ignore-fill-prefix nil) | ||
| 1765 | (fill-prefix (progn (beginning-of-line) | ||
| 1766 | (looking-at comment-line-start-skip) | ||
| 1767 | (match-string 0)))) | ||
| 1768 | (let (fill-paragraph-function) | ||
| 1769 | (fill-region start end justify))) ; with normal `fill-paragraph' | ||
| 1770 | (set-marker start nil) | ||
| 1771 | (set-marker end nil))))) | ||
| 1772 | |||
| 1773 | (defun fortran-fill-statement () | ||
| 1774 | "Fill a fortran statement up to `fill-column'." | ||
| 1775 | (interactive) | ||
| 1776 | (if (not (save-excursion | ||
| 1777 | (beginning-of-line) | ||
| 1778 | (or (looking-at "[ \t]*$") | ||
| 1779 | (looking-at comment-line-start-skip) | ||
| 1780 | (and comment-start-skip | ||
| 1781 | (looking-at (concat "[ \t]*" comment-start-skip)))))) | ||
| 1782 | (save-excursion | ||
| 1783 | ;; Find beginning of statement. | ||
| 1784 | (fortran-next-statement) | ||
| 1785 | (fortran-previous-statement) | ||
| 1786 | ;; Re-indent initially. | ||
| 1787 | (fortran-indent-line) | ||
| 1788 | ;; Replace newline plus continuation field plus indentation with | ||
| 1789 | ;; single space. | ||
| 1790 | (while (progn | ||
| 1791 | (forward-line) | ||
| 1792 | (fortran-remove-continuation))) | ||
| 1793 | (fortran-previous-statement))) | ||
| 1794 | (fortran-indent-line) | ||
| 1795 | t) ; must return t for fill-paragraph | ||
| 1796 | |||
| 1728 | (provide 'fortran) | 1797 | (provide 'fortran) |
| 1729 | 1798 | ||
| 1730 | ;;; fortran.el ends here | 1799 | ;;; fortran.el ends here |