aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/f90.el378
1 files changed, 203 insertions, 175 deletions
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 7f47db95540..5bf99165553 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -243,7 +243,7 @@ The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil."
243 :group 'f90) 243 :group 'f90)
244 244
245(defconst f90-xemacs-flag (string-match "XEmacs\\|Lucid" emacs-version) 245(defconst f90-xemacs-flag (string-match "XEmacs\\|Lucid" emacs-version)
246 "Non-nil means f90-mode thinks it is running under XEmacs.") 246 "Non-nil means F90 mode thinks it is running under XEmacs.")
247 247
248(defconst f90-keywords-re 248(defconst f90-keywords-re
249 (regexp-opt '("allocatable" "allocate" "assign" "assignment" "backspace" 249 (regexp-opt '("allocatable" "allocate" "assign" "assignment" "backspace"
@@ -312,7 +312,7 @@ The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil."
312 312
313(defconst f90-hpf-keywords-re 313(defconst f90-hpf-keywords-re
314 (regexp-opt 314 (regexp-opt
315 ;; Intrinsic procedures 315 ;; Intrinsic procedures.
316 '("all_prefix" "all_scatter" "all_suffix" "any_prefix" 316 '("all_prefix" "all_scatter" "all_suffix" "any_prefix"
317 "any_scatter" "any_suffix" "copy_prefix" "copy_scatter" 317 "any_scatter" "any_suffix" "copy_prefix" "copy_scatter"
318 "copy_suffix" "count_prefix" "count_scatter" "count_suffix" 318 "copy_suffix" "count_prefix" "count_scatter" "count_suffix"
@@ -326,20 +326,20 @@ The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil."
326 "parity_prefix" "parity_scatter" "parity_suffix" "popcnt" "poppar" 326 "parity_prefix" "parity_scatter" "parity_suffix" "popcnt" "poppar"
327 "processors_shape" "product_prefix" "product_scatter" 327 "processors_shape" "product_prefix" "product_scatter"
328 "product_suffix" "sum_prefix" "sum_scatter" "sum_suffix" 328 "product_suffix" "sum_prefix" "sum_scatter" "sum_suffix"
329 ;; Directives 329 ;; Directives.
330 "align" "distribute" "dynamic" "independent" "inherit" "processors" 330 "align" "distribute" "dynamic" "independent" "inherit" "processors"
331 "realign" "redistribute" "template" 331 "realign" "redistribute" "template"
332 ;; Keywords 332 ;; Keywords.
333 "block" "cyclic" "extrinsic" "new" "onto" "pure" "with") 'words) 333 "block" "cyclic" "extrinsic" "new" "onto" "pure" "with") 'words)
334 "Regexp for all HPF keywords, procedures and directives.") 334 "Regexp for all HPF keywords, procedures and directives.")
335 335
336;; Highlighting patterns 336;; Highlighting patterns.
337 337
338(defvar f90-font-lock-keywords-1 338(defvar f90-font-lock-keywords-1
339 (list 339 (list
340 ;; Special highlighting of "module procedure foo-list" 340 ;; Special highlighting of "module procedure".
341 '("\\<\\(module[ \t]*procedure\\)\\>" (1 font-lock-keyword-face)) 341 '("\\<\\(module[ \t]*procedure\\)\\>" (1 font-lock-keyword-face))
342 ;; Highlight definition of new type 342 ;; Highlight declaration of derived type.
343;;; '("\\<\\(type\\)[ \t]*\\(.*::[ \t]*\\|[ \t]+\\)\\(\\sw+\\)" 343;;; '("\\<\\(type\\)[ \t]*\\(.*::[ \t]*\\|[ \t]+\\)\\(\\sw+\\)"
344;;; (1 font-lock-keyword-face) (3 font-lock-function-name-face)) 344;;; (1 font-lock-keyword-face) (3 font-lock-function-name-face))
345 ;; Other functions and declarations. 345 ;; Other functions and declarations.
@@ -353,18 +353,18 @@ subroutine\\|type\\)\\|use\\|call\\)\\>[ \t]*\\(\\sw+\\)?"
353 (append 353 (append
354 f90-font-lock-keywords-1 354 f90-font-lock-keywords-1
355 (list 355 (list
356 ;; Variable declarations (avoid the real function call) 356 ;; Variable declarations (avoid the real function call).
357 '("^[ \t0-9]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\\|\ 357 '("^[ \t0-9]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\\|\
358logical\\|type[ \t]*(\\sw+)\\)\\(.*::\\|[ \t]*(.*)\\)?\\([^!\n]*\\)" 358logical\\|type[ \t]*(\\sw+)\\)\\(.*::\\|[ \t]*(.*)\\)?\\([^!\n]*\\)"
359 (1 font-lock-type-face t) (4 font-lock-variable-name-face)) 359 (1 font-lock-type-face t) (4 font-lock-variable-name-face))
360 ;; do, if, select, where, and forall constructs 360 ;; do, if, select, where, and forall constructs.
361 '("\\<\\(end[ \t]*\\(do\\|if\\|select\\|forall\\|where\\)\\)\\>\ 361 '("\\<\\(end[ \t]*\\(do\\|if\\|select\\|forall\\|where\\)\\)\\>\
362\\([ \t]+\\(\\sw+\\)\\)?" 362\\([ \t]+\\(\\sw+\\)\\)?"
363 (1 font-lock-keyword-face) (3 font-lock-constant-face nil t)) 363 (1 font-lock-keyword-face) (3 font-lock-constant-face nil t))
364 '("^[ \t0-9]*\\(\\(\\sw+\\)[ \t]*:[ \t]*\\)?\\(\\(if\\|\ 364 '("^[ \t0-9]*\\(\\(\\sw+\\)[ \t]*:[ \t]*\\)?\\(\\(if\\|\
365do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>" 365do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
366 (2 font-lock-constant-face nil t) (3 font-lock-keyword-face)) 366 (2 font-lock-constant-face nil t) (3 font-lock-keyword-face))
367 ;; implicit declaration 367 ;; Implicit declaration.
368 '("\\<\\(implicit\\)[ \t]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\ 368 '("\\<\\(implicit\\)[ \t]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\
369\\|logical\\|type[ \t]*(\\sw+)\\|none\\)\\>" 369\\|logical\\|type[ \t]*(\\sw+)\\|none\\)\\>"
370 (1 font-lock-keyword-face) (2 font-lock-type-face)) 370 (1 font-lock-keyword-face) (2 font-lock-type-face))
@@ -387,7 +387,7 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
387 f90-keywords-level-3-re 387 f90-keywords-level-3-re
388 f90-operators-re 388 f90-operators-re
389 (list f90-procedures-re '(1 font-lock-keyword-face keep)) 389 (list f90-procedures-re '(1 font-lock-keyword-face keep))
390 "\\<real\\>" ; Avoid overwriting real defs. 390 "\\<real\\>" ; avoid overwriting real defs
391 )) 391 ))
392 "Highlights all F90 keywords and intrinsic procedures.") 392 "Highlights all F90 keywords and intrinsic procedures.")
393 393
@@ -400,27 +400,27 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
400 f90-font-lock-keywords-2 400 f90-font-lock-keywords-2
401 "*Default expressions to highlight in F90 mode.") 401 "*Default expressions to highlight in F90 mode.")
402 402
403;; syntax table 403
404(defvar f90-mode-syntax-table nil 404(defvar f90-mode-syntax-table nil
405 "Syntax table in use in F90 mode buffers.") 405 "Syntax table in use in F90 mode buffers.")
406 406
407(unless f90-mode-syntax-table 407(unless f90-mode-syntax-table
408 (setq f90-mode-syntax-table (make-syntax-table)) 408 (setq f90-mode-syntax-table (make-syntax-table))
409 (modify-syntax-entry ?\! "<" f90-mode-syntax-table) ; beg. comment 409 (modify-syntax-entry ?\! "<" f90-mode-syntax-table) ; begin comment
410 (modify-syntax-entry ?\n ">" f90-mode-syntax-table) ; end comment 410 (modify-syntax-entry ?\n ">" f90-mode-syntax-table) ; end comment
411 (modify-syntax-entry ?_ "w" f90-mode-syntax-table) ; underscore in names 411 (modify-syntax-entry ?_ "w" f90-mode-syntax-table) ; underscore in names
412 (modify-syntax-entry ?\' "\"" f90-mode-syntax-table) ; string quote 412 (modify-syntax-entry ?\' "\"" f90-mode-syntax-table) ; string quote
413 (modify-syntax-entry ?\" "\"" f90-mode-syntax-table) ; string quote 413 (modify-syntax-entry ?\" "\"" f90-mode-syntax-table) ; string quote
414 (modify-syntax-entry ?\` "w" f90-mode-syntax-table) ; for abbrevs 414 (modify-syntax-entry ?\` "w" f90-mode-syntax-table) ; for abbrevs
415 (modify-syntax-entry ?\r " " f90-mode-syntax-table) ; return is whitespace 415 (modify-syntax-entry ?\r " " f90-mode-syntax-table) ; return is whitespace
416 (modify-syntax-entry ?+ "." f90-mode-syntax-table) 416 (modify-syntax-entry ?+ "." f90-mode-syntax-table) ; punctuation
417 (modify-syntax-entry ?- "." f90-mode-syntax-table) 417 (modify-syntax-entry ?- "." f90-mode-syntax-table)
418 (modify-syntax-entry ?= "." f90-mode-syntax-table) 418 (modify-syntax-entry ?= "." f90-mode-syntax-table)
419 (modify-syntax-entry ?* "." f90-mode-syntax-table) 419 (modify-syntax-entry ?* "." f90-mode-syntax-table)
420 (modify-syntax-entry ?/ "." f90-mode-syntax-table) 420 (modify-syntax-entry ?/ "." f90-mode-syntax-table)
421 (modify-syntax-entry ?\\ "\\" f90-mode-syntax-table)) ; escape chars 421 (modify-syntax-entry ?\\ "\\" f90-mode-syntax-table)) ; escape chars
422 422
423;; keys 423
424(defvar f90-mode-map () 424(defvar f90-mode-map ()
425 "Keymap used in F90 mode.") 425 "Keymap used in F90 mode.")
426 426
@@ -435,7 +435,7 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
435 (define-key f90-mode-map "\C-j" 'f90-indent-new-line) ; LFD equals C-j 435 (define-key f90-mode-map "\C-j" 'f90-indent-new-line) ; LFD equals C-j
436 (define-key f90-mode-map "\r" 'newline) 436 (define-key f90-mode-map "\r" 'newline)
437 (define-key f90-mode-map "\C-c\r" 'f90-break-line) 437 (define-key f90-mode-map "\C-c\r" 'f90-break-line)
438 ;; (define-key f90-mode-map [M-return] 'f90-break-line) 438;;; (define-key f90-mode-map [M-return] 'f90-break-line)
439 (define-key f90-mode-map "\C-c\C-d" 'f90-join-lines) 439 (define-key f90-mode-map "\C-c\C-d" 'f90-join-lines)
440 (define-key f90-mode-map "\C-c\C-f" 'f90-fill-region) 440 (define-key f90-mode-map "\C-c\C-f" 'f90-fill-region)
441 (define-key f90-mode-map "\C-c\C-p" 'f90-previous-statement) 441 (define-key f90-mode-map "\C-c\C-p" 'f90-previous-statement)
@@ -449,7 +449,6 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
449 (define-key f90-mode-map "/" 'f90-electric-insert)) 449 (define-key f90-mode-map "/" 'f90-electric-insert))
450 450
451 451
452;; menus
453(if f90-xemacs-flag 452(if f90-xemacs-flag
454 (defvar f90-xemacs-menu 453 (defvar f90-xemacs-menu
455 '("F90" 454 '("F90"
@@ -468,43 +467,40 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
468 ["Insert Block End" f90-insert-end t] 467 ["Insert Block End" f90-insert-end t]
469 "-----" 468 "-----"
470 ["Upcase Keywords (buffer)" f90-upcase-keywords t] 469 ["Upcase Keywords (buffer)" f90-upcase-keywords t]
471 ["Upcase Keywords (region)" f90-upcase-region-keywords 470 ["Upcase Keywords (region)" f90-upcase-region-keywords t]
472 t]
473 ["Capitalize Keywords (buffer)" f90-capitalize-keywords t] 471 ["Capitalize Keywords (buffer)" f90-capitalize-keywords t]
474 ["Capitalize Keywords (region)" 472 ["Capitalize Keywords (region)" f90-capitalize-region-keywords t]
475 f90-capitalize-region-keywords t]
476 ["Downcase Keywords (buffer)" f90-downcase-keywords t] 473 ["Downcase Keywords (buffer)" f90-downcase-keywords t]
477 ["Downcase Keywords (region)" 474 ["Downcase Keywords (region)" f90-downcase-region-keywords t]
478 f90-downcase-region-keywords t]
479 "-----" 475 "-----"
480 ["Toggle abbrev-mode" abbrev-mode t] 476 ["Toggle abbrev-mode" abbrev-mode t]
481 ["Toggle auto-fill" auto-fill-mode t]) 477 ["Toggle auto-fill" auto-fill-mode t])
482 "XEmacs menu for F90 mode.") 478 "XEmacs menu for F90 mode.")
483 ;; Emacs
484 479
480 ;; Emacs.
485 (defvar f90-change-case-menu 481 (defvar f90-change-case-menu
486 (let ((map (make-sparse-keymap "Change Keyword Case"))) 482 (let ((map (make-sparse-keymap "Change Keyword Case")))
487 (define-key map [dkr] (cons "Downcase Keywords (region)" 483 (define-key map [dkr]
488 'f90-downcase-region-keywords)) 484 (cons "Downcase Keywords (region)" 'f90-downcase-region-keywords))
489 (put 'f90-downcase-region-keywords 'menu-enable 'mark-active) 485 (put 'f90-downcase-region-keywords 'menu-enable 'mark-active)
490 (define-key map [ckr] (cons "Capitalize Keywords (region)" 486 (define-key map [ckr]
491 'f90-capitalize-region-keywords)) 487 (cons "Capitalize Keywords (region)" 'f90-capitalize-region-keywords))
492 (put 'f90-capitalize-region-keywords 'menu-enable 'mark-active) 488 (put 'f90-capitalize-region-keywords 'menu-enable 'mark-active)
493 (define-key map [ukr] (cons "Upcase Keywords (region)" 489 (define-key map [ukr]
494 'f90-upcase-region-keywords)) 490 (cons "Upcase Keywords (region)" 'f90-upcase-region-keywords))
495 (put 'f90-upcase-region-keywords 'menu-enable 'mark-active) 491 (put 'f90-upcase-region-keywords 'menu-enable 'mark-active)
496 (define-key map [line] (list "-----------------")) 492 (define-key map [line] (list "-----------------"))
497 (define-key map [dkb] (cons "Downcase Keywords (buffer)" 493 (define-key map [dkb]
498 'f90-downcase-keywords)) 494 (cons "Downcase Keywords (buffer)" 'f90-downcase-keywords))
499 (define-key map [ckb] (cons "Capitalize Keywords (buffer)" 495 (define-key map [ckb]
500 'f90-capitalize-keywords)) 496 (cons "Capitalize Keywords (buffer)" 'f90-capitalize-keywords))
501 (define-key map [ukb] (cons "Upcase Keywords (buffer)" 497 (define-key map [ukb]
502 'f90-upcase-keywords)) 498 (cons "Upcase Keywords (buffer)" 'f90-upcase-keywords))
503 map) 499 map)
504 "Submenu for change of case.") 500 "Submenu for change of case.")
505 (defalias 'f90-change-case-menu f90-change-case-menu) 501 (defalias 'f90-change-case-menu f90-change-case-menu)
506 502
507 ;; font-lock-menu and function calls 503 ;; Font-lock-menu and function calls.
508 (defalias 'f90-font-lock-on 'font-lock-mode) 504 (defalias 'f90-font-lock-on 'font-lock-mode)
509 (defalias 'f90-font-lock-off 'font-lock-mode) 505 (defalias 'f90-font-lock-off 'font-lock-mode)
510 (put 'f90-font-lock-on 'menu-enable 'font-lock-mode) 506 (put 'f90-font-lock-on 'menu-enable 'font-lock-mode)
@@ -540,21 +536,22 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
540 536
541 (defvar f90-font-lock-menu 537 (defvar f90-font-lock-menu
542 (let ((map (make-sparse-keymap "f90-font-lock-menu"))) 538 (let ((map (make-sparse-keymap "f90-font-lock-menu")))
543 (define-key map [h4] (cons "Maximum highlighting (level 4)" 539 (define-key map [h4]
544 'f90-font-lock-4)) 540 (cons "Maximum highlighting (level 4)" 'f90-font-lock-4))
545 (define-key map [h3] (cons "Heavy highlighting (level 3)" 541 (define-key map [h3]
546 'f90-font-lock-3)) 542 (cons "Heavy highlighting (level 3)" 'f90-font-lock-3))
547 (define-key map [h2] (cons "Default highlighting (level 2)" 543 (define-key map [h2]
548 'f90-font-lock-2)) 544 (cons "Default highlighting (level 2)" 'f90-font-lock-2))
549 (define-key map [h1] (cons "Light highlighting (level 1)" 545 (define-key map [h1]
550 'f90-font-lock-1)) 546 (cons "Light highlighting (level 1)" 'f90-font-lock-1))
551 (define-key map [line] (list "-----------------")) 547 (define-key map [line] (list "-----------------"))
552 (define-key map [floff] (cons "Turn off font-lock-mode" 548 (define-key map [floff]
553 'f90-font-lock-on)) 549 (cons "Turn off font-lock-mode" 'f90-font-lock-on))
554 (define-key map [flon] (cons "Turn on font-lock-mode" 550 (define-key map [flon]
555 'f90-font-lock-off)) 551 (cons "Turn on font-lock-mode" 'f90-font-lock-off))
556 map) 552 map)
557 "Submenu for highlighting using font-lock-mode.") 553 "Submenu for highlighting using font-lock-mode.")
554
558 (defalias 'f90-font-lock-menu f90-font-lock-menu) 555 (defalias 'f90-font-lock-menu f90-font-lock-menu)
559 556
560 (define-key f90-mode-map [menu-bar] (make-sparse-keymap)) 557 (define-key f90-mode-map [menu-bar] (make-sparse-keymap))
@@ -566,22 +563,19 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
566 '("Toggle abbrev-mode" . abbrev-mode)) 563 '("Toggle abbrev-mode" . abbrev-mode))
567 (define-key f90-mode-map [menu-bar f90 auto-fill-mode] 564 (define-key f90-mode-map [menu-bar f90 auto-fill-mode]
568 '("Toggle auto-fill" . auto-fill-mode)) 565 '("Toggle auto-fill" . auto-fill-mode))
569 (define-key f90-mode-map [menu-bar f90 line1] 566 (define-key f90-mode-map [menu-bar f90 line1] '("----"))
570 '("----"))
571 (define-key f90-mode-map [menu-bar f90 f90-change-case-menu] 567 (define-key f90-mode-map [menu-bar f90 f90-change-case-menu]
572 (cons "Change Keyword Case" 'f90-change-case-menu)) 568 (cons "Change Keyword Case" 'f90-change-case-menu))
573 (define-key f90-mode-map [menu-bar f90 f90-font-lock-menu] 569 (define-key f90-mode-map [menu-bar f90 f90-font-lock-menu]
574 (cons "Highlighting" 'f90-font-lock-menu)) 570 (cons "Highlighting" 'f90-font-lock-menu))
575 (define-key f90-mode-map [menu-bar f90 line2] 571 (define-key f90-mode-map [menu-bar f90 line2] '("----"))
576 '("----"))
577 (define-key f90-mode-map [menu-bar f90 f90-insert-end] 572 (define-key f90-mode-map [menu-bar f90 f90-insert-end]
578 '("Insert Block End" . f90-insert-end)) 573 '("Insert Block End" . f90-insert-end))
579 (define-key f90-mode-map [menu-bar f90 f90-join-lines] 574 (define-key f90-mode-map [menu-bar f90 f90-join-lines]
580 '("Join with Next Line" . f90-join-lines)) 575 '("Join with Next Line" . f90-join-lines))
581 (define-key f90-mode-map [menu-bar f90 f90-break-line] 576 (define-key f90-mode-map [menu-bar f90 f90-break-line]
582 '("Break Line at Point" . f90-break-line)) 577 '("Break Line at Point" . f90-break-line))
583 (define-key f90-mode-map [menu-bar f90 line3] 578 (define-key f90-mode-map [menu-bar f90 line3] '("----"))
584 '("----"))
585 (define-key f90-mode-map [menu-bar f90 f90-fill-region] 579 (define-key f90-mode-map [menu-bar f90 f90-fill-region]
586 '("Fill Region" . f90-fill-region)) 580 '("Fill Region" . f90-fill-region))
587 (put 'f90-fill-region 'menu-enable 'mark-active) 581 (put 'f90-fill-region 'menu-enable 'mark-active)
@@ -590,8 +584,7 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
590 (define-key f90-mode-map [menu-bar f90 f90-comment-region] 584 (define-key f90-mode-map [menu-bar f90 f90-comment-region]
591 '("(Un)Comment Region" . f90-comment-region)) 585 '("(Un)Comment Region" . f90-comment-region))
592 (put 'f90-comment-region 'menu-enable 'mark-active) 586 (put 'f90-comment-region 'menu-enable 'mark-active)
593 (define-key f90-mode-map [menu-bar f90 line4] 587 (define-key f90-mode-map [menu-bar f90 line4] '("----"))
594 '("----"))
595 (define-key f90-mode-map [menu-bar f90 f90-end-of-subprogram] 588 (define-key f90-mode-map [menu-bar f90 f90-end-of-subprogram]
596 '("End of Subprogram" . f90-end-of-subprogram)) 589 '("End of Subprogram" . f90-end-of-subprogram))
597 (define-key f90-mode-map [menu-bar f90 f90-beginning-of-subprogram] 590 (define-key f90-mode-map [menu-bar f90 f90-beginning-of-subprogram]
@@ -604,28 +597,48 @@ do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
604 597
605;; Regexps for finding program structures. 598;; Regexps for finding program structures.
606(defconst f90-blocks-re 599(defconst f90-blocks-re
607 "\\(block[ \t]*data\\|do\\|if\\|interface\\|function\\|module\\|\ 600 (concat "\\(block[ \t]*data\\|"
608program\\|select\\|subroutine\\|type\\|where\\|forall\\)\\>") 601 (regexp-opt '("do" "if" "interface" "function" "module" "program"
602 "select" "subroutine" "type" "where" "forall"))
603 "\\)\\>")
604 "Regexp potentially indicating a \"block\" of F90 code.")
605
609(defconst f90-program-block-re 606(defconst f90-program-block-re
610 "\\(program\\|module\\|subroutine\\|function\\)") 607 (regexp-opt '("program" "module" "subroutine" "function") 'paren)
608 "Regexp used to locate the start/end of a \"subprogram\".")
609
611(defconst f90-else-like-re 610(defconst f90-else-like-re
612 "\\(else\\([ \t]*if\\|where\\)?\\|case[ \t]*\\(default\\|(\\)\\)") 611 "\\(else\\([ \t]*if\\|where\\)?\\|case[ \t]*\\(default\\|(\\)\\)"
612 "Regexp matching an ELSE IF, ELSEWHERE, CASE statement.")
613
613(defconst f90-end-if-re 614(defconst f90-end-if-re
614 "end[ \t]*\\(if\\|select\\|where\\|forall\\)\\>") 615 (concat "end[ \t]*"
616 (regexp-opt '("if" "select" "where" "forall") 'paren)
617 "\\>")
618 "Regexp matching the end of an IF, SELECT, WHERE, FORALL block.")
619
615(defconst f90-end-type-re 620(defconst f90-end-type-re
616 "end[ \t]*\\(type\\|interface\\|block[ \t]*data\\)") 621 "end[ \t]*\\(type\\|interface\\|block[ \t]*data\\)\\>"
622 "Regexp matching the end of a TYPE, INTERFACE, BLOCK DATA section.")
623
617(defconst f90-type-def-re 624(defconst f90-type-def-re
618 "\\<\\(type\\)\\([^(\n]*\\)\\(::\\)?[ \t]*\\b\\(\\sw+\\)") 625 "\\<\\(type\\)\\([^(\n]*\\)\\(::\\)?[ \t]*\\b\\(\\sw+\\)"
619(defconst f90-no-break-re "\\(\\*\\*\\|//\\|=>\\)") 626 "Regexp matching the declaration of a variable of derived type.")
620;; A temporary position to make region operators faster 627
621(defvar f90-cache-position nil) 628(defconst f90-no-break-re
629 (regexp-opt '("**" "//" "=>") 'paren)
630 "Regexp specifying where not to break lines when filling.")
631
632(defvar f90-cache-position nil
633 "Temporary position used to speed up region operations.")
622(make-variable-buffer-local 'f90-cache-position) 634(make-variable-buffer-local 'f90-cache-position)
623;; A flag to tell whether f90-imenu is turned on. 635
624(defvar f90-imenu nil) 636(defvar f90-imenu-flag nil
625(make-variable-buffer-local 'f90-imenu) 637 "Non-nil means this buffer already has an imenu.")
638(make-variable-buffer-local 'f90-imenu-flag)
626 639
627 640
628;; Imenu support 641;; Imenu support.
629(defvar f90-imenu-generic-expression 642(defvar f90-imenu-generic-expression
630 (let ((good-char "[^!\"\&\n \t]") (not-e "[^e!\n\"\& \t]") 643 (let ((good-char "[^!\"\&\n \t]") (not-e "[^e!\n\"\& \t]")
631 (not-n "[^n!\n\"\& \t]") (not-d "[^d!\n\"\& \t]")) 644 (not-n "[^n!\n\"\& \t]") (not-d "[^d!\n\"\& \t]"))
@@ -638,14 +651,14 @@ program\\|select\\|subroutine\\|type\\|where\\|forall\\)\\>")
638 (concat 651 (concat
639 "^[ \t0-9]*" 652 "^[ \t0-9]*"
640 "\\(" 653 "\\("
641 ;; At least three non-space characters before function/subroutine 654 ;; At least three non-space characters before function/subroutine.
642 ;; Check that the last three non-space characters don't spell E N D 655 ;; Check that the last three non-space characters do not spell E N D.
643 "[^!\"\&\n]*\\(" 656 "[^!\"\&\n]*\\("
644 not-e good-char good-char "\\|" 657 not-e good-char good-char "\\|"
645 good-char not-n good-char "\\|" 658 good-char not-n good-char "\\|"
646 good-char good-char not-d "\\)" 659 good-char good-char not-d "\\)"
647 "\\|" 660 "\\|"
648 ;; Less than three non-space characters before function/subroutine 661 ;; Less than three non-space characters before function/subroutine.
649 good-char "?" good-char "?" 662 good-char "?" good-char "?"
650 "\\)" 663 "\\)"
651 "[ \t]*\\(function\\|subroutine\\)[ \t]+\\(\\sw+\\)") 664 "[ \t]*\\(function\\|subroutine\\)[ \t]+\\(\\sw+\\)")
@@ -655,21 +668,21 @@ program\\|select\\|subroutine\\|type\\|where\\|forall\\)\\>")
655(defun f90-add-imenu-menu () 668(defun f90-add-imenu-menu ()
656 "Add an imenu menu to the menubar." 669 "Add an imenu menu to the menubar."
657 (interactive) 670 (interactive)
658 (if f90-imenu 671 (if f90-imenu-flag
659 (message "%s" "F90-imenu already exists.") 672 (message "%s" "F90-imenu already exists.")
660 (imenu-add-to-menubar "F90-imenu") 673 (imenu-add-to-menubar "F90-imenu")
661 (redraw-frame (selected-frame)) 674 (redraw-frame (selected-frame))
662 (setq f90-imenu t))) 675 (setq f90-imenu-flag t)))
663 676
664(put 'f90-add-imenu-menu 'menu-enable '(not f90-imenu)) 677(put 'f90-add-imenu-menu 'menu-enable '(not f90-imenu-flag))
665 678
666 679
667;; When compiling under GNU Emacs, load imenu during compilation. If 680;; When compiling under GNU Emacs, load imenu during compilation.
668;; you have 19.22 or earlier, comment this out, or get imenu. 681;; If you have 19.22 or earlier, comment this out, or get imenu.
669(or f90-xemacs-flag (eval-when-compile (require 'imenu))) 682(or f90-xemacs-flag (eval-when-compile (require 'imenu)))
670 683
671 684
672;; abbrevs have generally two letters, except standard types `c, `i, `r, `t 685;; Abbrevs have generally two letters, except standard types `c, `i, `r, `t.
673(defvar f90-mode-abbrev-table nil) 686(defvar f90-mode-abbrev-table nil)
674(unless f90-mode-abbrev-table 687(unless f90-mode-abbrev-table
675 (let ((ac abbrevs-changed)) 688 (let ((ac abbrevs-changed))
@@ -730,7 +743,7 @@ program\\|select\\|subroutine\\|type\\|where\\|forall\\)\\>")
730 (setq abbrevs-changed ac))) 743 (setq abbrevs-changed ac)))
731 744
732(defcustom f90-mode-hook nil 745(defcustom f90-mode-hook nil
733 "Hook run by F90 mode." 746 "Hook run when entering F90 mode."
734 :type 'hook 747 :type 'hook
735 :options '(f90-add-imenu-menu) 748 :options '(f90-add-imenu-menu)
736 :group 'f90) 749 :group 'f90)
@@ -739,9 +752,9 @@ program\\|select\\|subroutine\\|type\\|where\\|forall\\)\\>")
739(defun f90-mode () 752(defun f90-mode ()
740 "Major mode for editing Fortran 90,95 code in free format. 753 "Major mode for editing Fortran 90,95 code in free format.
741 754
742\\[f90-indent-new-line] corrects current indentation and creates new\ 755\\[f90-indent-new-line] indents current line and creates a new\
743 indented line. 756 indented line.
744\\[f90-indent-line] indents the current line correctly. 757\\[f90-indent-line] indents the current line.
745\\[f90-indent-subprogram] indents the current subprogram. 758\\[f90-indent-subprogram] indents the current subprogram.
746 759
747Type `? or `\\[help-command] to display a list of built-in\ 760Type `? or `\\[help-command] to display a list of built-in\
@@ -752,45 +765,45 @@ Key definitions:
752 765
753Variables controlling indentation style and extra features: 766Variables controlling indentation style and extra features:
754 767
755 `f90-do-indent' 768`f90-do-indent'
756 Extra indentation within do blocks. (default 3) 769 Extra indentation within do blocks (default 3).
757 `f90-if-indent' 770`f90-if-indent'
758 Extra indentation within if/select case/where/forall blocks. (default 3) 771 Extra indentation within if/select case/where/forall blocks (default 3).
759 `f90-type-indent' 772`f90-type-indent'
760 Extra indentation within type/interface/block-data blocks. (default 3) 773 Extra indentation within type/interface/block-data blocks (default 3).
761 `f90-program-indent' 774`f90-program-indent'
762 Extra indentation within program/module/subroutine/function blocks. 775 Extra indentation within program/module/subroutine/function blocks
763 (default 2) 776 (default 2).
764 `f90-continuation-indent' 777`f90-continuation-indent'
765 Extra indentation applied to continuation lines. (default 5) 778 Extra indentation applied to continuation lines (default 5).
766 `f90-comment-region' 779`f90-comment-region'
767 String inserted by \\[f90-comment-region] at start of each line in 780 String inserted by \\[f90-comment-region] at start of each line in
768 region. (default \"!!!$\") 781 region (default \"!!!$\").
769 `f90-indented-comment-re' 782`f90-indented-comment-re'
770 Regexp determining the type of comment to be intended like code. 783 Regexp determining the type of comment to be intended like code
771 (default \"!\") 784 (default \"!\").
772 `f90-directive-comment-re' 785`f90-directive-comment-re'
773 Regexp of comment-like directive like \"!HPF\\\\$\", not to be indented. 786 Regexp of comment-like directive like \"!HPF\\\\$\", not to be indented
774 (default \"!hpf\\\\$\") 787 (default \"!hpf\\\\$\").
775 `f90-break-delimiters' 788`f90-break-delimiters'
776 Regexp holding list of delimiters at which lines may be broken. 789 Regexp holding list of delimiters at which lines may be broken
777 (default \"[-+*/><=,% \\t]\") 790 (default \"[-+*/><=,% \\t]\").
778 `f90-break-before-delimiters' 791`f90-break-before-delimiters'
779 Non-nil causes `f90-do-auto-fill' to break lines before delimiters. 792 Non-nil causes `f90-do-auto-fill' to break lines before delimiters
780 (default t) 793 (default t).
781 `f90-beginning-ampersand' 794`f90-beginning-ampersand'
782 Automatic insertion of \& at beginning of continuation lines. (default t) 795 Automatic insertion of \& at beginning of continuation lines (default t).
783 `f90-smart-end' 796`f90-smart-end'
784 From an END statement, check and fill the end using matching block start. 797 From an END statement, check and fill the end using matching block start.
785 Allowed values are 'blink, 'no-blink, and nil, which determine 798 Allowed values are 'blink, 'no-blink, and nil, which determine
786 whether to blink the matching beginning. (default 'blink) 799 whether to blink the matching beginning (default 'blink).
787 `f90-auto-keyword-case' 800`f90-auto-keyword-case'
788 Automatic change of case of keywords. (default nil) 801 Automatic change of case of keywords (default nil).
789 The possibilities are 'downcase-word, 'upcase-word, 'capitalize-word. 802 The possibilities are 'downcase-word, 'upcase-word, 'capitalize-word.
790 `f90-leave-line-no' 803`f90-leave-line-no'
791 Do not left-justify line numbers. (default nil) 804 Do not left-justify line numbers (default nil).
792 `f90-keywords-re' 805`f90-keywords-re'
793 List of keywords used for highlighting/upcase-keywords etc. 806 List of keywords used for highlighting/upcase-keywords etc.
794 807
795Turning on F90 mode calls the value of the variable `f90-mode-hook' 808Turning on F90 mode calls the value of the variable `f90-mode-hook'
796with no args, if that value is non-nil." 809with no args, if that value is non-nil."
@@ -818,7 +831,7 @@ with no args, if that value is non-nil."
818 (make-local-variable 'normal-auto-fill-function) 831 (make-local-variable 'normal-auto-fill-function)
819 (setq normal-auto-fill-function 'f90-do-auto-fill) 832 (setq normal-auto-fill-function 'f90-do-auto-fill)
820 (setq indent-tabs-mode nil) 833 (setq indent-tabs-mode nil)
821 ;; Setting up things for font-lock 834 ;; Setting up things for font-lock.
822 (when f90-xemacs-flag 835 (when f90-xemacs-flag
823 (put 'f90-mode 'font-lock-keywords-case-fold-search t) 836 (put 'f90-mode 'font-lock-keywords-case-fold-search t)
824 (when (and (featurep 'menubar) 837 (when (and (featurep 'menubar)
@@ -826,7 +839,7 @@ with no args, if that value is non-nil."
826 (not (assoc "F90" current-menubar))) 839 (not (assoc "F90" current-menubar)))
827 (set-buffer-menubar (copy-sequence current-menubar)) 840 (set-buffer-menubar (copy-sequence current-menubar))
828 (add-submenu nil f90-xemacs-menu))) 841 (add-submenu nil f90-xemacs-menu)))
829 ;; XEmacs: (Don't need a special case, since both emacsen work alike -sb) 842 ;; XEmacs: Does not need a special case, since both emacsen work alike -sb.
830 (make-local-variable 'font-lock-defaults) 843 (make-local-variable 'font-lock-defaults)
831 (setq font-lock-defaults 844 (setq font-lock-defaults
832 '((f90-font-lock-keywords f90-font-lock-keywords-1 845 '((f90-font-lock-keywords f90-font-lock-keywords-1
@@ -841,11 +854,12 @@ with no args, if that value is non-nil."
841 (set (make-local-variable 'add-log-current-defun-function) 854 (set (make-local-variable 'add-log-current-defun-function)
842 #'f90-current-defun) 855 #'f90-current-defun)
843 (run-hooks 'f90-mode-hook)) 856 (run-hooks 'f90-mode-hook))
857
844 858
845;; inline-functions 859;; Inline-functions.
846(defsubst f90-in-string () 860(defsubst f90-in-string ()
847 "Return non-nil if point is inside a string. 861 "Return non-nil if point is inside a string.
848Checks from point-min, or f90-cache-position, if that is non-nil 862Checks from `point-min', or `f90-cache-position', if that is non-nil
849and lies before point." 863and lies before point."
850 (let ((beg-pnt 864 (let ((beg-pnt
851 (if (and f90-cache-position (> (point) f90-cache-position)) 865 (if (and f90-cache-position (> (point) f90-cache-position))
@@ -855,7 +869,7 @@ and lies before point."
855 869
856(defsubst f90-in-comment () 870(defsubst f90-in-comment ()
857 "Return non-nil if point is inside a comment. 871 "Return non-nil if point is inside a comment.
858Checks from point-min, or f90-cache-position, if that is non-nil 872Checks from `point-min', or `f90-cache-position', if that is non-nil
859and lies before point." 873and lies before point."
860 (let ((beg-pnt 874 (let ((beg-pnt
861 (if (and f90-cache-position (> (point) f90-cache-position)) 875 (if (and f90-cache-position (> (point) f90-cache-position))
@@ -910,14 +924,13 @@ For example, \"!\" or \"!!\"."
910 type))) 924 type)))
911 925
912(defsubst f90-equal-symbols (a b) 926(defsubst f90-equal-symbols (a b)
913 "Compare strings neglecting case and allowing for nil value." 927 "Compare strings A and B neglecting case and allowing for nil value."
914 (let ((a-local (if a (downcase a) nil)) 928 (let ((a-local (if a (downcase a) nil))
915 (b-local (if b (downcase b) nil))) 929 (b-local (if b (downcase b) nil)))
916 (equal a-local b-local))) 930 (equal a-local b-local)))
917 931
918;; XEmacs 19.11 & 19.12 gives back a single char when matching an empty regular 932;; XEmacs 19.11 & 19.12 return a single char when matching an empty regexp.
919;; expression. Therefore, the next 2 functions are longer than necessary. 933;; The next 2 functions are therefore longer than necessary.
920
921(defsubst f90-looking-at-do () 934(defsubst f90-looking-at-do ()
922 "Return (\"do\" NAME) if a do statement starts after point. 935 "Return (\"do\" NAME) if a do statement starts after point.
923NAME is nil if the statement has no label." 936NAME is nil if the statement has no label."
@@ -998,6 +1011,11 @@ NAME is non-nil only for type."
998 (list (match-string 1) (match-string 3)))) 1011 (list (match-string 1) (match-string 3))))
999 1012
1000(defsubst f90-comment-indent () 1013(defsubst f90-comment-indent ()
1014 "Return the indentation to be used for a comment starting at point.
1015Used for `comment-indent-function' by F90 mode.
1016\"!!!\", `f90-directive-comment-re', variable `f90-comment-region' return 0.
1017`f90-indented-comment-re' (if not trailing code) calls `f90-calculate-indent'.
1018Any other type return `comment-column', leaving at least one space after code."
1001 (cond ((looking-at "!!!") 0) 1019 (cond ((looking-at "!!!") 0)
1002 ((and f90-directive-comment-re 1020 ((and f90-directive-comment-re
1003 (looking-at f90-directive-comment-re)) 0) 1021 (looking-at f90-directive-comment-re)) 0)
@@ -1138,7 +1156,7 @@ Does not check type and subprogram indentation."
1138 (goto-char pnt) 1156 (goto-char pnt)
1139 (beginning-of-line) 1157 (beginning-of-line)
1140 (cond ((looking-at "[ \t]*$")) 1158 (cond ((looking-at "[ \t]*$"))
1141 ((looking-at "[ \t]*#") ; Check for cpp directive. 1159 ((looking-at "[ \t]*#") ; check for cpp directive
1142 (setq icol 0)) 1160 (setq icol 0))
1143 (t 1161 (t
1144 (skip-chars-forward " \t0-9") 1162 (skip-chars-forward " \t0-9")
@@ -1155,10 +1173,10 @@ Does not check type and subprogram indentation."
1155 )))) 1173 ))))
1156 icol)) 1174 icol))
1157 1175
1158;; Statement = statement line, a line which is neither blank, nor a comment.
1159(defun f90-previous-statement () 1176(defun f90-previous-statement ()
1160 "Move point to beginning of the previous F90 statement. 1177 "Move point to beginning of the previous F90 statement.
1161Return nil if no previous statement is found." 1178Return nil if no previous statement is found.
1179A statement is a line which is neither blank nor a comment."
1162 (interactive) 1180 (interactive)
1163 (let (not-first-statement) 1181 (let (not-first-statement)
1164 (beginning-of-line) 1182 (beginning-of-line)
@@ -1180,7 +1198,7 @@ Return nil if no later statement is found."
1180 1198
1181(defun f90-beginning-of-subprogram () 1199(defun f90-beginning-of-subprogram ()
1182 "Move point to the beginning of subprogram. 1200 "Move point to the beginning of subprogram.
1183Return (type name) or nil if not found." 1201Return (TYPE NAME), or nil if not found."
1184 (interactive) 1202 (interactive)
1185 (let ((count 1) (case-fold-search t) matching-beg) 1203 (let ((count 1) (case-fold-search t) matching-beg)
1186 (beginning-of-line) (skip-chars-forward " \t0-9") 1204 (beginning-of-line) (skip-chars-forward " \t0-9")
@@ -1197,12 +1215,12 @@ Return (type name) or nil if not found."
1197 (beginning-of-line) 1215 (beginning-of-line)
1198 (if (zerop count) 1216 (if (zerop count)
1199 matching-beg 1217 matching-beg
1200 (message "No beginning-found.") 1218 (message "No beginning found.")
1201 nil))) 1219 nil)))
1202 1220
1203(defun f90-end-of-subprogram () 1221(defun f90-end-of-subprogram ()
1204 "Move point to the end of subprogram. 1222 "Move point to the end of subprogram.
1205Return (type name) or nil if not found." 1223Return (TYPE NAME), or nil if not found."
1206 (interactive) 1224 (interactive)
1207 (let ((count 1) (case-fold-search t) matching-end) 1225 (let ((count 1) (case-fold-search t) matching-end)
1208 (beginning-of-line) (skip-chars-forward " \t0-9") 1226 (beginning-of-line) (skip-chars-forward " \t0-9")
@@ -1277,7 +1295,7 @@ after indenting."
1277 (interactive) 1295 (interactive)
1278 (let (indent (no-line-number nil) (pos (make-marker)) (case-fold-search t)) 1296 (let (indent (no-line-number nil) (pos (make-marker)) (case-fold-search t))
1279 (set-marker pos (point)) 1297 (set-marker pos (point))
1280 (beginning-of-line) ; Digits after & \n are not line-no 1298 (beginning-of-line) ; digits after & \n are not line-nos
1281 (if (save-excursion (and (f90-previous-statement) (f90-line-continued))) 1299 (if (save-excursion (and (f90-previous-statement) (f90-line-continued)))
1282 (progn (setq no-line-number t) (skip-chars-forward " \t")) 1300 (progn (setq no-line-number t) (skip-chars-forward " \t"))
1283 (f90-indent-line-no)) 1301 (f90-indent-line-no))
@@ -1305,12 +1323,11 @@ If run in the middle of a line, the line is not broken."
1305 (interactive) 1323 (interactive)
1306 (let (string cont (case-fold-search t)) 1324 (let (string cont (case-fold-search t))
1307 (if abbrev-mode (expand-abbrev)) 1325 (if abbrev-mode (expand-abbrev))
1308 (beginning-of-line) ; Reindent where likely to be needed. 1326 (beginning-of-line) ; reindent where likely to be needed
1309 (f90-indent-line-no) 1327 (f90-indent-line-no)
1310 (if (or (looking-at "\\(end\\|else\\|!\\)")) 1328 (f90-indent-line 'no-update)
1311 (f90-indent-line 'no-update))
1312 (end-of-line) 1329 (end-of-line)
1313 (delete-horizontal-space) ;Destroy trailing whitespace 1330 (delete-horizontal-space) ; destroy trailing whitespace
1314 (setq string (f90-in-string)) 1331 (setq string (f90-in-string))
1315 (setq cont (f90-line-continued)) 1332 (setq cont (f90-line-continued))
1316 (if (and string (not cont)) (insert "&")) 1333 (if (and string (not cont)) (insert "&"))
@@ -1328,7 +1345,7 @@ If run in the middle of a line, the line is not broken."
1328 struct beg-struct end-struct) 1345 struct beg-struct end-struct)
1329 (set-marker end-region-mark end-region) 1346 (set-marker end-region-mark end-region)
1330 (goto-char beg-region) 1347 (goto-char beg-region)
1331 ;; first find a line which is not a continuation line or comment 1348 ;; First find a line which is not a continuation line or comment.
1332 (beginning-of-line) 1349 (beginning-of-line)
1333 (while (and (looking-at "[ \t]*[0-9]*\\(!\\|#\\|[ \t]*$\\)") 1350 (while (and (looking-at "[ \t]*[0-9]*\\(!\\|#\\|[ \t]*$\\)")
1334 (progn (f90-indent-line 'no-update) 1351 (progn (f90-indent-line 'no-update)
@@ -1338,7 +1355,7 @@ If run in the middle of a line, the line is not broken."
1338 (while (and (or (eq cont 'middle) (eq cont 'end)) 1355 (while (and (or (eq cont 'middle) (eq cont 'end))
1339 (f90-previous-statement)) 1356 (f90-previous-statement))
1340 (setq cont (f90-present-statement-cont))) 1357 (setq cont (f90-present-statement-cont)))
1341 ;; process present line for beginning of block 1358 ;; Process present line for beginning of block.
1342 (setq f90-cache-position (point)) 1359 (setq f90-cache-position (point))
1343 (f90-indent-line 'no-update) 1360 (f90-indent-line 'no-update)
1344 (setq ind-lev (f90-current-indentation)) 1361 (setq ind-lev (f90-current-indentation))
@@ -1360,10 +1377,12 @@ If run in the middle of a line, the line is not broken."
1360 (if struct (setq block-list (cons struct block-list))) 1377 (if struct (setq block-list (cons struct block-list)))
1361 (while (and (f90-line-continued) (zerop (forward-line 1)) 1378 (while (and (f90-line-continued) (zerop (forward-line 1))
1362 (< (point) end-region-mark)) 1379 (< (point) end-region-mark))
1363 (if (not (zerop (- (current-indentation) 1380 (if (looking-at "[ \t]*!")
1364 (+ ind-curr f90-continuation-indent)))) 1381 (f90-indent-to (f90-comment-indent))
1365 (f90-indent-to (+ ind-curr f90-continuation-indent) 'no-line-no))) 1382 (if (not (zerop (- (current-indentation)
1366 ;; process all following lines 1383 (+ ind-curr f90-continuation-indent))))
1384 (f90-indent-to (+ ind-curr f90-continuation-indent) 'no-line-no))))
1385 ;; Process all following lines.
1367 (while (and (zerop (forward-line 1)) (< (point) end-region-mark)) 1386 (while (and (zerop (forward-line 1)) (< (point) end-region-mark))
1368 (beginning-of-line) 1387 (beginning-of-line)
1369 (f90-indent-line-no) 1388 (f90-indent-line-no)
@@ -1394,8 +1413,8 @@ If run in the middle of a line, the line is not broken."
1394 block-list (cdr block-list)) 1413 block-list (cdr block-list))
1395 (if f90-smart-end 1414 (if f90-smart-end
1396 (save-excursion 1415 (save-excursion
1397 (f90-block-match (car beg-struct)(car (cdr beg-struct)) 1416 (f90-block-match (car beg-struct) (car (cdr beg-struct))
1398 (car end-struct)(car (cdr end-struct))))) 1417 (car end-struct) (car (cdr end-struct)))))
1399 (setq ind-b 1418 (setq ind-b
1400 (cond ((looking-at f90-end-if-re) f90-if-indent) 1419 (cond ((looking-at f90-end-if-re) f90-if-indent)
1401 ((looking-at "end[ \t]*do\\>") f90-do-indent) 1420 ((looking-at "end[ \t]*do\\>") f90-do-indent)
@@ -1405,15 +1424,18 @@ If run in the middle of a line, the line is not broken."
1405 (if ind-b (setq ind-lev (- ind-lev ind-b))) 1424 (if ind-b (setq ind-lev (- ind-lev ind-b)))
1406 (setq ind-curr ind-lev)) 1425 (setq ind-curr ind-lev))
1407 (t (setq ind-curr ind-lev))) 1426 (t (setq ind-curr ind-lev)))
1408 ;; do the indentation if necessary 1427 ;; Do the indentation if necessary.
1409 (if (not (zerop (- ind-curr (current-column)))) 1428 (if (not (zerop (- ind-curr (current-column))))
1410 (f90-indent-to ind-curr)) 1429 (f90-indent-to ind-curr))
1411 (while (and (f90-line-continued) (zerop (forward-line 1)) 1430 (while (and (f90-line-continued) (zerop (forward-line 1))
1412 (< (point) end-region-mark)) 1431 (< (point) end-region-mark))
1413 (if (not (zerop (- (current-indentation) 1432 (if (looking-at "[ \t]*!")
1414 (+ ind-curr f90-continuation-indent)))) 1433 (f90-indent-to (f90-comment-indent))
1415 (f90-indent-to (+ ind-curr f90-continuation-indent) 'no-line-no)))) 1434 (if (not (zerop (- (current-indentation)
1416 ;; restore point etc 1435 (+ ind-curr f90-continuation-indent))))
1436 (f90-indent-to
1437 (+ ind-curr f90-continuation-indent) 'no-line-no)))))
1438 ;; Restore point, etc.
1417 (setq f90-cache-position nil) 1439 (setq f90-cache-position nil)
1418 (goto-char save-point) 1440 (goto-char save-point)
1419 (set-marker end-region-mark nil) 1441 (set-marker end-region-mark nil)
@@ -1423,7 +1445,7 @@ If run in the middle of a line, the line is not broken."
1423 (deactivate-mark)))) 1445 (deactivate-mark))))
1424 1446
1425(defun f90-indent-subprogram () 1447(defun f90-indent-subprogram ()
1426 "Properly indent the subprogram which contains point." 1448 "Properly indent the subprogram containing point."
1427 (interactive) 1449 (interactive)
1428 (save-excursion 1450 (save-excursion
1429 (let (program) 1451 (let (program)
@@ -1439,7 +1461,6 @@ If run in the middle of a line, the line is not broken."
1439 (indent-region (point) (mark) nil) 1461 (indent-region (point) (mark) nil)
1440 (message "Indenting the whole file...done"))))) 1462 (message "Indenting the whole file...done")))))
1441 1463
1442;; autofill and break-line
1443(defun f90-break-line (&optional no-update) 1464(defun f90-break-line (&optional no-update)
1444 "Break line at point, insert continuation marker(s) and indent. 1465 "Break line at point, insert continuation marker(s) and indent.
1445Unless in a string or comment, or if the optional argument NO-UPDATE 1466Unless in a string or comment, or if the optional argument NO-UPDATE
@@ -1474,9 +1495,9 @@ is non-nil, call `f90-update-line' after inserting the continuation marker."
1474 "Break line if non-white characters beyond `fill-column'. 1495 "Break line if non-white characters beyond `fill-column'.
1475Update keyword case first." 1496Update keyword case first."
1476 (interactive) 1497 (interactive)
1477 ;; Break the line before or after the last delimiter (non-word char) if 1498 ;; Break line before or after last delimiter (non-word char) if
1478 ;; position is beyond fill-column. 1499 ;; position is beyond fill-column.
1479 ;; Will not break **, //, or => (specified by f90-no-break-re). 1500 ;; Will not break **, //, or => (as specified by f90-no-break-re).
1480 (f90-update-line) 1501 (f90-update-line)
1481 (while (> (current-column) fill-column) 1502 (while (> (current-column) fill-column)
1482 (let ((pos-mark (point-marker))) 1503 (let ((pos-mark (point-marker)))
@@ -1521,9 +1542,9 @@ Update keyword case first."
1521 (set-marker end-region-mark end-region) 1542 (set-marker end-region-mark end-region)
1522 (goto-char beg-region) 1543 (goto-char beg-region)
1523 (while go-on 1544 (while go-on
1524 ;; join as much as possible 1545 ;; Join as much as possible.
1525 (while (f90-join-lines)) 1546 (while (f90-join-lines))
1526 ;; chop the line if necessary 1547 ;; Chop the line if necessary.
1527 (while (> (save-excursion (end-of-line) (current-column)) 1548 (while (> (save-excursion (end-of-line) (current-column))
1528 fill-column) 1549 fill-column)
1529 (move-to-column fill-column) 1550 (move-to-column fill-column)
@@ -1539,6 +1560,10 @@ Update keyword case first."
1539 1560
1540(defun f90-block-match (beg-block beg-name end-block end-name) 1561(defun f90-block-match (beg-block beg-name end-block end-name)
1541 "Match end-struct with beg-struct and complete end-block if possible. 1562 "Match end-struct with beg-struct and complete end-block if possible.
1563BEG-BLOCK is the type of block as indicated at the start (e.g., do).
1564BEG-NAME is the block start name (may be nil).
1565END-BLOCK is the type of block as indicated at the end (may be nil).
1566END-NAME is the block end name (may be nil).
1542Leave point at the end of line." 1567Leave point at the end of line."
1543 (search-forward "end" (line-end-position)) 1568 (search-forward "end" (line-end-position))
1544 (catch 'no-match 1569 (catch 'no-match
@@ -1567,7 +1592,7 @@ Leave point at the end of line."
1567 (if (not (looking-at "[ \t]*!")) (delete-horizontal-space)))) 1592 (if (not (looking-at "[ \t]*!")) (delete-horizontal-space))))
1568 1593
1569(defun f90-match-end () 1594(defun f90-match-end ()
1570 "From an end foo statement, find the corresponding foo including name." 1595 "From an end block statement, find the corresponding block and name."
1571 (interactive) 1596 (interactive)
1572 (let ((count 1) (top-of-window (window-start)) (matching-beg nil) 1597 (let ((count 1) (top-of-window (window-start)) (matching-beg nil)
1573 (end-point (point)) (case-fold-search t) 1598 (end-point (point)) (case-fold-search t)
@@ -1627,7 +1652,7 @@ Leave point at the end of line."
1627 (insert "end") 1652 (insert "end")
1628 (f90-indent-new-line))) 1653 (f90-indent-new-line)))
1629 1654
1630;; abbrevs and keywords 1655;; Abbrevs and keywords.
1631 1656
1632(defun f90-abbrev-start () 1657(defun f90-abbrev-start ()
1633 "Typing `\\[help-command] or `? lists all the F90 abbrevs. 1658 "Typing `\\[help-command] or `? lists all the F90 abbrevs.
@@ -1639,7 +1664,7 @@ Any other key combination is executed normally."
1639 (setq c (read-event)) 1664 (setq c (read-event))
1640 (setq e (next-command-event) 1665 (setq e (next-command-event)
1641 c (event-to-character e))) 1666 c (event-to-character e)))
1642 ;; insert char if not equal to `?' 1667 ;; Insert char if not equal to `?'.
1643 (if (or (eq c ??) (eq c help-char)) 1668 (if (or (eq c ??) (eq c help-char))
1644 (f90-abbrev-help) 1669 (f90-abbrev-help)
1645 (if f90-xemacs-flag 1670 (if f90-xemacs-flag
@@ -1654,6 +1679,7 @@ Any other key combination is executed normally."
1654 (message "Listing abbrev table...done")) 1679 (message "Listing abbrev table...done"))
1655 1680
1656(defun f90-prepare-abbrev-list-buffer () 1681(defun f90-prepare-abbrev-list-buffer ()
1682 "Create a buffer listing the F90 mode abbreviations."
1657 (save-excursion 1683 (save-excursion
1658 (set-buffer (get-buffer-create "*Abbrevs*")) 1684 (set-buffer (get-buffer-create "*Abbrevs*"))
1659 (erase-buffer) 1685 (erase-buffer)
@@ -1695,6 +1721,8 @@ Any other key combination is executed normally."
1695 1721
1696;; Change the keywords according to argument. 1722;; Change the keywords according to argument.
1697(defun f90-change-keywords (change-word &optional beg end) 1723(defun f90-change-keywords (change-word &optional beg end)
1724 "Change the case of F90 keywords in the region (if specified) or buffer.
1725CHANGE-WORD should be one of 'upcase-word, 'downcase-word, capitalize-word."
1698 (save-excursion 1726 (save-excursion
1699 (setq beg (if beg beg (point-min))) 1727 (setq beg (if beg beg (point-min)))
1700 (setq end (if end end (point-max))) 1728 (setq end (if end end (point-max)))
@@ -1710,7 +1738,7 @@ Any other key combination is executed normally."
1710 (unless (progn 1738 (unless (progn
1711 (setq state (parse-partial-sexp ref-point (point))) 1739 (setq state (parse-partial-sexp ref-point (point)))
1712 (or (nth 3 state) (nth 4 state) 1740 (or (nth 3 state) (nth 4 state)
1713 (save-excursion ; Check for cpp directive. 1741 (save-excursion ; check for cpp directive
1714 (beginning-of-line) 1742 (beginning-of-line)
1715 (skip-chars-forward " \t0-9") 1743 (skip-chars-forward " \t0-9")
1716 (looking-at "#")))) 1744 (looking-at "#"))))