comparison lisp/progmodes/fortran.el @ 43882:e601e469e7a4

(fortran-mode): Set comment-padding to "$$$". Add fortran-comment-line-start-skip to comment-start-skip. (fortran-comment-indent): Keep whole-line comments in column 0. (fortran-find-comment-start-skip): New arg `all'. If ALL is nil, make sure we only match comment-start-skip if we can't match fortran-comment-line-start-skip. Fix bug that made it return t but without moving point when matching '!'! (a false-comment followed by a real comment). (fortran-indent-comment): Use new `all' argument above. Be careful not to add an incorrect comment-starter like "C" in comment-column. (fortran-split-line): When splitting a comment, reuse the comment starter from the current line rather than fortran-comment-line-start. (fortran-indent-line, fortran-auto-fill): Simplify thanks to the cleaner behavior of fortran-find-comment-start-skip. (fortran-fill): Don't be confused by ! inside a comment. (fortran-break-line): Minor cleanup and simplification.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 13 Mar 2002 16:33:56 +0000
parents 6f5de421ceca
children b13e662ea2b3
comparison
equal deleted inserted replaced
43881:e9654452ad5e 43882:e601e469e7a4
106 :group 'fortran-indent) 106 :group 'fortran-indent)
107 107
108 (defcustom fortran-comment-indent-style 'fixed 108 (defcustom fortran-comment-indent-style 'fixed
109 "*How to indent comments. 109 "*How to indent comments.
110 nil forces comment lines not to be touched, 110 nil forces comment lines not to be touched,
111 'fixed makes fixed comment indentation to `fortran-comment-line-extra-indent' 111 `fixed' makes fixed comment indentation to `fortran-comment-line-extra-indent'
112 columns beyond `fortran-minimum-statement-indent-fixed' (for 112 columns beyond `fortran-minimum-statement-indent-fixed' (for
113 `indent-tabs-mode' of nil) or `fortran-minimum-statement-indent-tab' (for 113 `indent-tabs-mode' of nil) or `fortran-minimum-statement-indent-tab' (for
114 `indent-tabs-mode' of t), and 'relative indents to current 114 `indent-tabs-mode' of t), and
115 Fortran indentation plus `fortran-comment-line-extra-indent'." 115 `relative' indents to current Fortran indentation plus
116 `fortran-comment-line-extra-indent'."
116 :type '(radio (const :tag "Untouched" nil) (const fixed) (const relative)) 117 :type '(radio (const :tag "Untouched" nil) (const fixed) (const relative))
117 :group 'fortran-indent) 118 :group 'fortran-indent)
118 119
119 (defcustom fortran-comment-line-extra-indent 0 120 (defcustom fortran-comment-line-extra-indent 0
120 "*Amount of extra indentation for text within full-line comments." 121 "*Amount of extra indentation for text within full-line comments."
635 (setq fortran-break-before-delimiters t) 636 (setq fortran-break-before-delimiters t)
636 (make-local-variable 'indent-line-function) 637 (make-local-variable 'indent-line-function)
637 (setq indent-line-function 'fortran-indent-line) 638 (setq indent-line-function 'fortran-indent-line)
638 (make-local-variable 'comment-indent-function) 639 (make-local-variable 'comment-indent-function)
639 (setq comment-indent-function 'fortran-comment-indent) 640 (setq comment-indent-function 'fortran-comment-indent)
640 (make-local-variable 'comment-start-skip) 641 (set (make-local-variable 'comment-start-skip)
641 (setq comment-start-skip "![ \t]*") 642 ;; We can't reuse `fortran-comment-line-start-skip' directly because
643 ;; it contains backrefs whereas we need submatch-1 to end at the
644 ;; beginning of the comment delimiter.
645 ;; (concat "\\(\\)\\(![ \t]*\\|" fortran-comment-line-start-skip "\\)")
646 "\\(\\)\\(?:^[CcDd*]\\|!\\)\\(?:\\([^ \t\n]\\)\\2+\\)?[ \t]*")
647 (set (make-local-variable 'comment-padding) "$$$")
642 (make-local-variable 'comment-start) 648 (make-local-variable 'comment-start)
643 (setq comment-start fortran-comment-line-start) 649 (setq comment-start fortran-comment-line-start)
644 (make-local-variable 'require-final-newline) 650 (make-local-variable 'require-final-newline)
645 (setq require-final-newline t) 651 (setq require-final-newline t)
646 (make-local-variable 'abbrev-all-caps) 652 (make-local-variable 'abbrev-all-caps)
679 (set (make-local-variable 'dabbrev-case-fold-search) 'case-fold-search) 685 (set (make-local-variable 'dabbrev-case-fold-search) 'case-fold-search)
680 (run-hooks 'fortran-mode-hook)) 686 (run-hooks 'fortran-mode-hook))
681 687
682 (defsubst fortran-comment-indent () 688 (defsubst fortran-comment-indent ()
683 (save-excursion 689 (save-excursion
684 (skip-chars-backward " \t") 690 (if (looking-at fortran-comment-line-start-skip) 0
685 (max (+ 1 (current-column)) 691 (skip-chars-backward " \t")
686 comment-column))) 692 (max (+ 1 (current-column))
693 comment-column))))
687 694
688 (defun fortran-indent-comment () 695 (defun fortran-indent-comment ()
689 "Align or create comment on current line. 696 "Align or create comment on current line.
690 Existing comments of all types are recognized and aligned. 697 Existing comments of all types are recognized and aligned.
691 If the line has no comment, a side-by-side comment is inserted and aligned 698 If the line has no comment, a side-by-side comment is inserted and aligned
692 if the value of `comment-start' is not nil. 699 if the value of `comment-start' is not nil and allows such comments.
693 Otherwise, a separate-line comment is inserted, on this line 700 Otherwise, a separate-line comment is inserted, on this line
694 or on a new line inserted before this line if this line is not blank." 701 or on a new line inserted before this line if this line is not blank."
695 (interactive) 702 (interactive)
696 (beginning-of-line) 703 (beginning-of-line)
697 ;; Recognize existing comments of either kind. 704 ;; Recognize existing comments of either kind.
698 (cond ((looking-at fortran-comment-line-start-skip) 705 (cond ((fortran-find-comment-start-skip 'all)
699 (fortran-indent-line)) 706 (goto-char (match-beginning 0))
700 ((fortran-find-comment-start-skip) ; catches any inline comment and 707 (if (bolp)
701 ; leaves point after comment-start-skip 708 (fortran-indent-line)
702 (if comment-start-skip 709 (if (not (= (current-column)
703 (progn (goto-char (match-beginning 0)) 710 (fortran-comment-indent)))
704 (if (not (= (current-column) 711 (progn (delete-horizontal-space)
705 (fortran-comment-indent))) 712 (indent-to (fortran-comment-indent))))))
706 (progn (delete-horizontal-space)
707 (indent-to (fortran-comment-indent)))))
708 (end-of-line))) ; otherwise goto end of line or sth else?
709 ;; No existing comment. 713 ;; No existing comment.
710 ;; If side-by-side comments are defined, insert one, 714 ;; If side-by-side comments are defined, insert one,
711 ;; unless line is now blank. 715 ;; unless line is now blank.
712 ((and comment-start (not (looking-at "^[ \t]*$"))) 716 ((and comment-start (not (looking-at "[ \t]*$"))
717 (string-match comment-start-skip (concat " " comment-start)))
713 (end-of-line) 718 (end-of-line)
714 (delete-horizontal-space) 719 (delete-horizontal-space)
715 (indent-to (fortran-comment-indent)) 720 (indent-to (fortran-comment-indent))
716 (insert comment-start)) 721 (insert comment-start))
717 ;; Else insert separate-line comment, making a new line if nec. 722 ;; Else insert separate-line comment, making a new line if nec.
839 (interactive) 844 (interactive)
840 (delete-horizontal-space) 845 (delete-horizontal-space)
841 (if (save-excursion 846 (if (save-excursion
842 (beginning-of-line) 847 (beginning-of-line)
843 (looking-at fortran-comment-line-start-skip)) 848 (looking-at fortran-comment-line-start-skip))
844 (insert ?\n fortran-comment-line-start ? ) 849 (insert ?\n (match-string 0))
845 (if indent-tabs-mode 850 (if indent-tabs-mode
846 (insert ?\n ?\t (fortran-numerical-continuation-char)) 851 (insert ?\n ?\t (fortran-numerical-continuation-char))
847 (insert "\n " fortran-continuation-string))) ; Space after \n important 852 (insert "\n " fortran-continuation-string))) ; Space after \n important
848 (fortran-indent-line)) ; when the cont string is C, c or *. 853 (fortran-indent-line)) ; when the cont string is C, c or *.
849 854
1235 (if (or (not (= cfi (fortran-current-line-indentation))) 1240 (if (or (not (= cfi (fortran-current-line-indentation)))
1236 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t) 1241 (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t)
1237 (not (fortran-line-number-indented-correctly-p)))) 1242 (not (fortran-line-number-indented-correctly-p))))
1238 (fortran-indent-to-column cfi) 1243 (fortran-indent-to-column cfi)
1239 (beginning-of-line) 1244 (beginning-of-line)
1240 (if (and (not (looking-at fortran-comment-line-start-skip)) 1245 (if (fortran-find-comment-start-skip)
1241 (fortran-find-comment-start-skip))
1242 (fortran-indent-comment)))) 1246 (fortran-indent-comment))))
1243 ;; Never leave point in left margin. 1247 ;; Never leave point in left margin.
1244 (if (< (current-column) cfi) 1248 (if (< (current-column) cfi)
1245 (move-to-column cfi)) 1249 (move-to-column cfi))
1246 (if (and auto-fill-function 1250 (if (and auto-fill-function
1263 (and (re-search-forward "^[ \t]*[0-9]+" 1267 (and (re-search-forward "^[ \t]*[0-9]+"
1264 (+ (point) 4) t) 1268 (+ (point) 4) t)
1265 (not (fortran-line-number-indented-correctly-p)))) 1269 (not (fortran-line-number-indented-correctly-p))))
1266 (fortran-indent-to-column cfi) 1270 (fortran-indent-to-column cfi)
1267 (beginning-of-line) 1271 (beginning-of-line)
1268 (if (and (not (looking-at fortran-comment-line-start-skip)) 1272 (if (fortran-find-comment-start-skip)
1269 (fortran-find-comment-start-skip))
1270 (fortran-indent-comment)))) 1273 (fortran-indent-comment))))
1271 (fortran-fill) 1274 (fortran-fill)
1272 ;; Never leave point in left margin. 1275 ;; Never leave point in left margin.
1273 (if (< (current-column) cfi) 1276 (if (< (current-column) cfi)
1274 (move-to-column cfi))))) 1277 (move-to-column cfi)))))
1463 ;; Point is now after any continuation character or line number. 1466 ;; Point is now after any continuation character or line number.
1464 ;; Put body of statement where specified. 1467 ;; Put body of statement where specified.
1465 (delete-horizontal-space) 1468 (delete-horizontal-space)
1466 (indent-to col) 1469 (indent-to col)
1467 ;; Indent any comment following code on the same line. 1470 ;; Indent any comment following code on the same line.
1468 (if (and comment-start-skip 1471 (if (fortran-find-comment-start-skip)
1469 (fortran-find-comment-start-skip))
1470 (progn (goto-char (match-beginning 0)) 1472 (progn (goto-char (match-beginning 0))
1471 (if (not (= (current-column) 1473 (if (not (= (current-column) (fortran-comment-indent)))
1472 (fortran-comment-indent)))
1473 (progn (delete-horizontal-space) 1474 (progn (delete-horizontal-space)
1474 (indent-to (fortran-comment-indent))))))))) 1475 (indent-to (fortran-comment-indent)))))))))
1475 1476
1476 (defun fortran-line-number-indented-correctly-p () 1477 (defun fortran-line-number-indented-correctly-p ()
1477 "Return t if current line's line number is correctly indented. 1478 "Return t if current line's line number is correctly indented.
1511 nil t) 1512 nil t)
1512 (looking-at 1513 (looking-at
1513 (concat "^[ \t0-9]*do[ \t]*0*" 1514 (concat "^[ \t0-9]*do[ \t]*0*"
1514 charnum)))))))))) 1515 charnum))))))))))
1515 1516
1516 (defun fortran-find-comment-start-skip () 1517 (defun fortran-find-comment-start-skip (&optional all)
1517 "Move to past `comment-start-skip' found on current line. 1518 "Move to past `comment-start-skip' found on current line.
1518 Return t if `comment-start-skip' found, nil if not." 1519 Return non-nil if `comment-start-skip' found, nil if not.
1519 ;; In order to move point only if comment-start-skip is found, this 1520 If ALL is nil, only match comments that start in column > 0."
1520 ;; one uses a lot of save-excursions. Note that re-search-forward
1521 ;; moves point even if comment-start-skip is inside a string-constant.
1522 ;; Some code expects certain values for match-beginning and end.
1523 (interactive) 1521 (interactive)
1524 (if (and comment-start-skip 1522 ;; Hopefully at some point we can just use the line below! -stef
1525 (save-excursion 1523 ;; (comment-search-forward (line-end-position) t))
1526 (re-search-forward comment-start-skip (line-end-position) t))) 1524 (when (or all comment-start-skip)
1527 (let ((save-match-beginning (match-beginning 0)) 1525 (let ((pos (point))
1528 (save-match-end (match-end 0))) 1526 (css (if comment-start-skip
1529 (if (fortran-is-in-string-p (match-beginning 0)) 1527 (concat fortran-comment-line-start-skip
1530 (save-excursion 1528 "\\|" comment-start-skip)
1531 (goto-char save-match-end) 1529 fortran-comment-line-start-skip)))
1532 (fortran-find-comment-start-skip)) ; recurse for rest of line 1530 (when (re-search-forward css (line-end-position) t)
1533 (goto-char save-match-beginning) 1531 (if (and (or all (> (match-beginning 0) (line-beginning-position)))
1534 (re-search-forward comment-start-skip (line-end-position) t) 1532 (or (save-match-data
1535 (goto-char (match-end 0)) 1533 (not (fortran-is-in-string-p (match-beginning 0))))
1536 t)))) 1534 ;; Recurse for rest of line.
1535 (fortran-find-comment-start-skip all)))
1536 (point)
1537 (goto-char pos)
1538 nil)))))
1537 1539
1538 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel) 1540 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel)
1539 ;; Test if TAB format continuation lines work. 1541 ;; Test if TAB format continuation lines work.
1540 (defun fortran-is-in-string-p (where) 1542 (defun fortran-is-in-string-p (where)
1541 "Return non-nil iff WHERE (a buffer position) is inside a Fortran string." 1543 "Return non-nil iff WHERE (a buffer position) is inside a Fortran string."
1647 ;; line of code is longer than it should be. Otherwise 1649 ;; line of code is longer than it should be. Otherwise
1648 ;; break the line at the column computed above. 1650 ;; break the line at the column computed above.
1649 ;; 1651 ;;
1650 ;; Need to use fortran-find-comment-start-skip to make sure that quoted !'s 1652 ;; Need to use fortran-find-comment-start-skip to make sure that quoted !'s
1651 ;; don't prevent a break. 1653 ;; don't prevent a break.
1652 (if (not (or (save-excursion 1654 (when (and (save-excursion
1653 (if (and comment-start-skip 1655 (beginning-of-line)
1654 (re-search-backward comment-start-skip bol t) 1656 (when (fortran-find-comment-start-skip)
1655 (not (fortran-is-in-string-p (point)))) 1657 (goto-char (match-beginning 0))
1656 (progn 1658 (>= (point) fill-point)))
1657 (skip-chars-backward " \t") 1659 (save-excursion
1658 (< (current-column) (1+ fill-column))))) 1660 (goto-char fill-point)
1659 (save-excursion 1661 (not (bolp)))
1660 (goto-char fill-point) 1662 (> (save-excursion
1661 (bolp)))) 1663 (goto-char opoint)
1662 (when (> (save-excursion 1664 (current-column))
1663 (goto-char opoint) 1665 (min (1+ fill-column)
1664 (current-column)) 1666 (+ (fortran-calculate-indent)
1665 (min (1+ fill-column) 1667 fortran-continuation-indent))))
1666 (+ (fortran-calculate-indent) 1668 (goto-char fill-point)
1667 fortran-continuation-indent))) 1669 (fortran-break-line)
1668 (goto-char fill-point) 1670 (end-of-line))))
1669 (fortran-break-line)
1670 (end-of-line)))))
1671 1671
1672 (defun fortran-break-line () 1672 (defun fortran-break-line ()
1673 (let ((opoint (point)) 1673 (let ((opoint (point))
1674 (bol (line-beginning-position)) 1674 (bol (line-beginning-position))
1675 (eol (line-end-position)) 1675 (comment-string
1676 (comment-string nil)) 1676 (save-excursion
1677 (save-excursion 1677 (if (fortran-find-comment-start-skip)
1678 (if (and comment-start-skip (fortran-find-comment-start-skip)) 1678 (delete-and-extract-region
1679 (progn 1679 (match-beginning 0) (line-end-position))))))
1680 (re-search-backward comment-start-skip bol t)
1681 (setq comment-string (buffer-substring (point) eol))
1682 (delete-region (point) eol))))
1683 ;; Forward line 1 really needs to go to next non white line 1680 ;; Forward line 1 really needs to go to next non white line
1684 (if (save-excursion (forward-line) 1681 (if (save-excursion (forward-line)
1685 (or (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]"))) 1682 (looking-at " \\{5\\}[^ 0\n]\\|\t[1-9]"))
1686 (progn 1683 (progn
1687 (end-of-line) 1684 (end-of-line)
1688 (delete-region (point) (match-end 0)) 1685 (delete-region (point) (match-end 0))
1689 (delete-horizontal-space) 1686 (delete-horizontal-space)
1690 (fortran-fill)) 1687 (fortran-fill))
1773 (if (not (save-excursion 1770 (if (not (save-excursion
1774 (beginning-of-line) 1771 (beginning-of-line)
1775 (or (looking-at "[ \t]*$") 1772 (or (looking-at "[ \t]*$")
1776 (looking-at fortran-comment-line-start-skip) 1773 (looking-at fortran-comment-line-start-skip)
1777 (and comment-start-skip 1774 (and comment-start-skip
1778 (looking-at (concat "[ \t]*" 1775 (looking-at (concat "[ \t]*" comment-start-skip))))))
1779 comment-start-skip))))))
1780 (save-excursion 1776 (save-excursion
1781 ;; Find beginning of statement. 1777 ;; Find beginning of statement.
1782 (fortran-next-statement) 1778 (fortran-next-statement)
1783 (fortran-previous-statement) 1779 (fortran-previous-statement)
1784 ;; Re-indent initially. 1780 ;; Re-indent initially.