comparison lisp/progmodes/fortran.el @ 25054:888326cb8ffb

(fortran-mode-syntax-table): Change `\' to `\' syntax. (fortran-fontify-string, fortran-match-!-commen): Deleted. (fortran-font-lock-syntactic-keywords): New variable. (fortran-mode): Use it. (fortran-font-lock-keywords-1): Don't do comments. (beginning-of-fortran-subprogram, end-of-fortran-subprogram): Save match data.
author Dave Love <fx@gnu.org>
date Sat, 24 Jul 1999 13:11:43 +0000
parents b4bf2212c418
children ec613559ec18
comparison
equal deleted inserted replaced
25053:c9241709321e 25054:888326cb8ffb
1 ;;; fortran.el --- Fortran mode for GNU Emacs 1 ;;; fortran.el --- Fortran mode for GNU Emacs
2 2
3 ;; Copyright (c) 1986, 1993, 1994, 1995, 1997, 1998 Free Software Foundation, Inc. 3 ;; Copyright (c) 1986, 93, 94, 95, 97, 98, 1999 Free Software Foundation, Inc.
4 4
5 ;; Author: Michael D. Prange <prange@erl.mit.edu> 5 ;; Author: Michael D. Prange <prange@erl.mit.edu>
6 ;; Maintainer: Dave Love <fx@gnu.org> 6 ;; Maintainer: Dave Love <fx@gnu.org>
7 ;; Keywords: languages 7 ;; Keywords: languages
8 8
233 (modify-syntax-entry ?= "." fortran-mode-syntax-table) 233 (modify-syntax-entry ?= "." fortran-mode-syntax-table)
234 (modify-syntax-entry ?* "." fortran-mode-syntax-table) 234 (modify-syntax-entry ?* "." fortran-mode-syntax-table)
235 (modify-syntax-entry ?/ "." fortran-mode-syntax-table) 235 (modify-syntax-entry ?/ "." fortran-mode-syntax-table)
236 (modify-syntax-entry ?\' "\"" fortran-mode-syntax-table) 236 (modify-syntax-entry ?\' "\"" fortran-mode-syntax-table)
237 (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table) 237 (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table)
238 (modify-syntax-entry ?\\ "/" fortran-mode-syntax-table) 238 (modify-syntax-entry ?\\ "\\" fortran-mode-syntax-table)
239 ;; This might be better as punctuation, as for C, but this way you 239 ;; This might be better as punctuation, as for C, but this way you
240 ;; can treat floating-point numbers as symbols. 240 ;; can treat floating-point numbers as symbols.
241 (modify-syntax-entry ?. "_" fortran-mode-syntax-table) ; e.g. `a.ne.b' 241 (modify-syntax-entry ?. "_" fortran-mode-syntax-table) ; e.g. `a.ne.b'
242 (modify-syntax-entry ?_ "_" fortran-mode-syntax-table) 242 (modify-syntax-entry ?_ "_" fortran-mode-syntax-table)
243 (modify-syntax-entry ?$ "_" fortran-mode-syntax-table) ; esp. VMSisms 243 (modify-syntax-entry ?$ "_" fortran-mode-syntax-table) ; esp. VMSisms
244 (modify-syntax-entry ?\! "<" fortran-mode-syntax-table) 244 (modify-syntax-entry ?\! "<" fortran-mode-syntax-table)
245 (modify-syntax-entry ?\n ">" fortran-mode-syntax-table)) 245 (modify-syntax-entry ?\n ">" fortran-mode-syntax-table))
246 246
247 ;; Comments are real pain in Fortran because there is no way to represent the 247 ;; Comments are real pain in Fortran because there is no way to
248 ;; standard comment syntax in an Emacs syntax table (we can for VAX-style). 248 ;; represent the standard comment syntax in an Emacs syntax table.
249 ;; Therefore an unmatched quote in a standard comment will throw fontification 249 ;; (We can do so for F90-style). Therefore an unmatched quote in a
250 ;; off on the wrong track. So we do syntactic fontification with regexps. 250 ;; standard comment will throw fontification off on the wrong track.
251 ;; So we do syntactic fontification with regexps.
251 252
252 ;; Regexps done by simon@gnu with help from Ulrik Dickow <dickow@nbi.dk> and 253 ;; Regexps done by simon@gnu with help from Ulrik Dickow <dickow@nbi.dk> and
253 ;; probably others Si's forgotten about (sorry). 254 ;; probably others Si's forgotten about (sorry).
254 255
255 (defconst fortran-font-lock-keywords-1 nil 256 (defconst fortran-font-lock-keywords-1 nil
259 "Medium level highlighting for Fortran mode.") 260 "Medium level highlighting for Fortran mode.")
260 261
261 (defconst fortran-font-lock-keywords-3 nil 262 (defconst fortran-font-lock-keywords-3 nil
262 "Gaudy level highlighting for Fortran mode.") 263 "Gaudy level highlighting for Fortran mode.")
263 264
264 (defun fortran-fontify-string (limit) 265 (defconst fortran-font-lock-syntactic-keywords nil
265 (let ((match (match-string 1))) 266 "`font-lock-syntactic-keywords' for Fortran.
266 (cond ((string= "'" match) 267 These get fixed-format comments fontified.")
267 (re-search-forward "\\([^'\n]*'?\\)" limit)) 268
268 ((string= "\"" match) 269 (let ((comment-chars "cd") ; `d' for `debugging' comments
269 (re-search-forward "\\([^\"\n]*\"?\\)" limit)))))
270
271 (let ((comment-chars "c!*d") ; `d' for `debugging' comments
272 (fortran-type-types 270 (fortran-type-types
273 (eval-when-compile 271 (eval-when-compile
274 (let ((re (regexp-opt 272 (let ((re (regexp-opt
275 (let ((simple-types 273 (let ((simple-types
276 '("character" "byte" "integer" "logical" 274 '("character" "byte" "integer" "logical"
302 (fortran-logicals 300 (fortran-logicals
303 (eval-when-compile 301 (eval-when-compile
304 (regexp-opt '("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne" 302 (regexp-opt '("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne"
305 "true" "false"))))) 303 "true" "false")))))
306 304
305 (setq fortran-font-lock-syntactic-keywords
306 ;; Fixed format comments. (!-style handled normally.)
307 (list
308 (list (concat "^[" comment-chars "]") 0 '(11))
309 (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.)
310 "\\([^\n]+\\)")
311 1 '(11))))
312
307 (setq fortran-font-lock-keywords-1 313 (setq fortran-font-lock-keywords-1
308 (list 314 (list
309 ;;
310 ;; Fontify syntactically (assuming strings cannot be quoted
311 ;; or span lines).
312 (cons (concat "^[" comment-chars "].*") 'font-lock-comment-face)
313 '(fortran-match-!-comment . font-lock-comment-face)
314 (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.)
315 "\\(.*\\)")
316 '(1 font-lock-comment-face))
317 '("\\(\\s\"\\)" ; single- or double-quoted string
318 (1 font-lock-string-face)
319 (fortran-fontify-string nil nil (1 font-lock-string-face)))
320 ;; 315 ;;
321 ;; Program, subroutine and function declarations, plus calls. 316 ;; Program, subroutine and function declarations, plus calls.
322 (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|" 317 (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|"
323 "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?") 318 "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?")
324 '(1 font-lock-keyword-face) 319 '(1 font-lock-keyword-face)
638 (make-local-variable 'font-lock-defaults) 633 (make-local-variable 'font-lock-defaults)
639 (setq font-lock-defaults '((fortran-font-lock-keywords 634 (setq font-lock-defaults '((fortran-font-lock-keywords
640 fortran-font-lock-keywords-1 635 fortran-font-lock-keywords-1
641 fortran-font-lock-keywords-2 636 fortran-font-lock-keywords-2
642 fortran-font-lock-keywords-3) 637 fortran-font-lock-keywords-3)
643 t t ((?/ . "$/") ("_$" . "w")))) 638 nil t ((?/ . "$/") ("_$" . "w"))
639 beginning-of-fortran-subprogram))
640 (set (make-local-variable 'font-lock-syntactic-keywords)
641 fortran-font-lock-syntactic-keywords)
644 (make-local-variable 'fortran-break-before-delimiters) 642 (make-local-variable 'fortran-break-before-delimiters)
645 (setq fortran-break-before-delimiters t) 643 (setq fortran-break-before-delimiters t)
646 (make-local-variable 'indent-line-function) 644 (make-local-variable 'indent-line-function)
647 (setq indent-line-function 'fortran-indent-line) 645 (setq indent-line-function 'fortran-indent-line)
648 (make-local-variable 'comment-indent-function) 646 (make-local-variable 'comment-indent-function)
949 ;; Note that you can't just check backwards for `subroutine' &c in 947 ;; Note that you can't just check backwards for `subroutine' &c in
950 ;; case of un-marked main programs not at the start of the file. 948 ;; case of un-marked main programs not at the start of the file.
951 (defun beginning-of-fortran-subprogram () 949 (defun beginning-of-fortran-subprogram ()
952 "Moves point to the beginning of the current Fortran subprogram." 950 "Moves point to the beginning of the current Fortran subprogram."
953 (interactive) 951 (interactive)
954 (let ((case-fold-search t)) 952 (save-match-data
955 (beginning-of-line -1) 953 (let ((case-fold-search t))
956 (if (catch 'ok 954 (beginning-of-line -1)
957 (while (re-search-backward fortran-end-prog-re nil 'move) 955 (if (catch 'ok
956 (while (re-search-backward fortran-end-prog-re nil 'move)
957 (if (fortran-check-end-prog-re)
958 (throw 'ok t))))
959 (forward-line)))))
960
961 (defun end-of-fortran-subprogram ()
962 "Moves point to the end of the current Fortran subprogram."
963 (interactive)
964 (save-match-data
965 (let ((case-fold-search t))
966 (if (save-excursion ; on END
967 (beginning-of-line)
968 (and (looking-at fortran-end-prog-re)
969 (fortran-check-end-prog-re)))
970 (forward-line)
971 (beginning-of-line 2)
972 (catch 'ok
973 (while (re-search-forward fortran-end-prog-re nil 'move)
958 (if (fortran-check-end-prog-re) 974 (if (fortran-check-end-prog-re)
959 (throw 'ok t)))) 975 (throw 'ok t))))
960 (forward-line)))) 976 (goto-char (match-beginning 0))
961 977 (forward-line)))))
962 (defun end-of-fortran-subprogram ()
963 "Moves point to the end of the current Fortran subprogram."
964 (interactive)
965 (let ((case-fold-search t))
966 (if (save-excursion ; on END
967 (beginning-of-line)
968 (and (looking-at fortran-end-prog-re)
969 (fortran-check-end-prog-re)))
970 (forward-line)
971 (beginning-of-line 2)
972 (catch 'ok
973 (while (re-search-forward fortran-end-prog-re nil 'move)
974 (if (fortran-check-end-prog-re)
975 (throw 'ok t))))
976 (goto-char (match-beginning 0))
977 (forward-line))))
978 978
979 (defun mark-fortran-subprogram () 979 (defun mark-fortran-subprogram ()
980 "Put mark at end of Fortran subprogram, point at beginning. 980 "Put mark at end of Fortran subprogram, point at beginning.
981 The marks are pushed." 981 The marks are pushed."
982 (interactive) 982 (interactive)
1590 (save-excursion (end-of-line) (point)) t) 1590 (save-excursion (end-of-line) (point)) t)
1591 (goto-char (match-end 0)) 1591 (goto-char (match-end 0))
1592 t)) 1592 t))
1593 nil)) 1593 nil))
1594 1594
1595 ;;From: simon@gnu (Simon Marshall)
1596 ;; Find the next ! not in a string.
1597 (defun fortran-match-!-comment (limit)
1598 (let (found)
1599 (while (and (setq found (search-forward "!" limit t))
1600 (fortran-is-in-string-p (point))))
1601 (if (not found)
1602 nil
1603 ;; Cheaper than `looking-at' "!.*".
1604 (set-match-data
1605 (list (1- (point)) (progn (end-of-line) (min (point) limit))))
1606 t)))
1607
1608 ;; The above function is about 10% faster than the below...
1609 ;;(defun fortran-match-!-comment (limit)
1610 ;; (let (found)
1611 ;; (while (and (setq found (re-search-forward "!.*" limit t))
1612 ;; (fortran-is-in-string-p (match-beginning 0))))
1613 ;; found))
1614
1615 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel) 1595 ;;From: ralf@up3aud1.gwdg.de (Ralf Fassel)
1616 ;; Test if TAB format continuation lines work. 1596 ;; Test if TAB format continuation lines work.
1617 (defun fortran-is-in-string-p (where) 1597 (defun fortran-is-in-string-p (where)
1618 "Return non-nil iff WHERE (a buffer position) is inside a Fortran string." 1598 "Return non-nil iff WHERE (a buffer position) is inside a Fortran string."
1619 (save-excursion 1599 (save-excursion