Subject: bug#38415: closed (Re: bug#38415: f90.el matching END statements)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 16 Jan 2020 02:56:02 +0000

Your bug report

#38415: f90.el matching END statements

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
38415: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=38415
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#38415: f90.el matching END statements
From: Glenn Morris <[email-masked]>
To: [email-masked]
Date: Wed, 15 Jan 2020 21:55:07 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

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

Subject: f90.el matching END statements
From: Salvatore Filippone <[email-masked]>
To: [email-masked]
Date: Thu, 28 Nov 2019 10:08:17 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

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