--- Begin Message ---
Subject: |
f90.el matching END statements |
Date: |
Thu, 28 Nov 2019 10:08:17 +0000 |
Dear All,
I have recently run into an issue with f90.el, version 26.2
distributed with fedora 30.
The issue is with the autocompletion feature; Fortran 2008 has
introduced submodules; among the changes entailed by this, it is now
possible to have a piece of code like the following:
--------------------
interface
module subroutine foo(bar)
integer :: bar
end subroutine foo
end interface
---------------------
Now, if I hit TAB on the first "end" the autocompletion feature tries to insert
end module subroutine
which is wrong, whereas I would like to insert
end subroutine foo
I have found a fix for this. I changed file f90.el:1385-1386 from
-------------
((and (not (looking-at "module[ \t]*procedure\\_>"))
(looking-at "\\(module\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>"))
--------------
to
--------------
((and (not (or
(looking-at "module[ \t]*procedure\\_>")
(looking-at "module[ \t]*subroutine\\_>")))
(looking-at "\\(module\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>"))
---------------
and I got the desired behaviour.
It is quite possible that somebody on this list will have a better
solution, but this does the job.
Hope this helps
Salvatore Filippone
--- End Message ---
--- Begin Message ---
Subject: |
Re: bug#38415: f90.el matching END statements |
Date: |
Wed, 15 Jan 2020 21:55:07 -0500 |
User-agent: |
Gnus (www.gnus.org), GNU Emacs (www.gnu.org/software/emacs/) |
Version: 27.1
Thanks for the report. I think this fixes it:
commit 3b0d1a5
Date: Wed Jan 15 18:47:51 2020 -0800
f90: handle F2008 module function
* lisp/progmodes/f90.el (f90-font-lock-keywords-1)
(f90-looking-at-program-block-start):
Handle F2008 "module function" and subroutine. (Bug#38415)
* test/lisp/progmodes/f90-tests.el (f90-test-bug38415): New test.
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index 92fba1c..9f61b8a 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -539,8 +539,10 @@ f90-font-lock-keywords-1
read\\|write\\)\\)[ \t]*(" (1 font-lock-keyword-face t))
;; Other functions and declarations. Named interfaces = F2003.
;; F2008: end submodule submodule_name.
- '("\\_<\\(\\(?:end[ \t]*\\)?\\(program\\|\\(?:sub\\)?module\\|\
-function\\|associate\\|subroutine\\|interface\\)\\|use\\|call\\)\
+ ;; F2008: module function|subroutine NAME.
+ '("\\_<\\(\\(?:end[ \t]*\\)?\\(program\\|\
+\\(?:module[ \t]*\\)?\\(?:function\\|subroutine\\)\\|\
+\\(?:sub\\)?module\\|associate\\|interface\\)\\|use\\|call\\)\
\\_>[ \t]*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
(1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
;; F2008: submodule (parent_name) submodule_name.
@@ -1381,14 +1383,19 @@ f90-looking-at-program-block-start
(cond
((looking-at "\\(program\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
(list (match-string 1) (match-string 2)))
- ((and (not (looking-at "module[ \t]*procedure\\_>"))
+ ((and (not (looking-at "module[
\t]*\\(procedure\\|function\\|subroutine\\)\\_>"))
(looking-at "\\(module\\)[ \t]+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>"))
(list (match-string 1) (match-string 2)))
((looking-at "\\(submodule\\)[ \t]*([^)\n]+)[
\t]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
(list (match-string 1) (match-string 2)))
- ((and (not (looking-at "end[ \t]*\\(function\\|subroutine\\)"))
- (looking-at "[^!'\"&\n]*\\(function\\|subroutine\\)[ \t]+\
+ ((and (not (looking-at "end[ \t]*\\(function\\|procedure\\|subroutine\\)"))
+ (looking-at "[^!'\"&\n]*\\(?:module[ \t]*\\)?\
+\\(function\\|subroutine\\)[ \t]+\
\\(\\(?:\\sw\\|\\s_\\)+\\)"))
+ ;; TODO: In F2008 "module procedure foo" may or may not start a block,
+ ;; It is impossible to tell the difference without parsing state.
+;;; (looking-at "[^!'\"&\n]*module[ \t]*\\(procedure\\)[ \t]+\
+;;;\\(\\(?:\\sw\\|\\s_\\)+\\)")))
(list (match-string 1) (match-string 2)))))
;; Following will match an un-named main program block; however
;; one needs to check if there is an actual PROGRAM statement after
diff --git a/test/lisp/progmodes/f90-tests.el b/test/lisp/progmodes/f90-tests.el
index 540082c..b6fbac3 100644
--- a/test/lisp/progmodes/f90-tests.el
+++ b/test/lisp/progmodes/f90-tests.el
@@ -277,4 +277,24 @@ f90-test-indent
(forward-line -2)
(should (= 2 (current-indentation))))) ; type is
+(ert-deftest f90-test-bug38415 ()
+ "Test for https://debbugs.gnu.org/38415 ."
+ (with-temp-buffer
+ (f90-mode)
+ (setq-local f90-smart-end 'no-blink)
+ (insert "module function foo(x)
+real :: x
+end")
+ (f90-indent-line)
+ (should (equal " function foo"
+ (buffer-substring (point) (line-end-position))))
+ (goto-char (point-max))
+ (insert "\nmodule subroutine bar(x)
+real :: x
+end")
+ (f90-indent-line)
+ (should (equal " subroutine bar"
+ (buffer-substring (point) (line-end-position))))))
+
+
;;; f90-tests.el ends here
--- End Message ---