Homepage: https://github.com/wence-/f90-iface
Author: Lawrence Mitchell
Updated:
Parse and browse f90 interfaces
You write (or work on) large, modern fortran code bases. These
make heavy use of function overloading and generic interfaces. Your
brain is too small to remember what all the specialisers are
called. Therefore, your editor should help you.
Load this file and tell it to parse all the fortran files in your
code base. You can do this one directory at a time by calling
`f90-parse-interfaces-in-dir' (M-x f90-parse-interfaces-in-dir
RET). Or you can parse all the fortran files in a directory and
recursively in its subdirectories by calling
`f90-parse-all-interfaces'.
Now you are able to browse (with completion) all defined interfaces
in your code by calling `f90-browse-interface-specialisers'.
Alternatively, if `point' is on a procedure call, you can call
`f90-find-tag-interface' and you'll be shown a list of the
interfaces that match the (possibly typed) argument list of the
current procedure. This latter falls back on Xref so that you can bind
it to the `M-.' and it will fall back to completing tag names if you
don't want to look for an interface definition.
In addition, if you're in a large procedure and want the list of
the variables in scope (perhaps you want to define a new loop
variable), you can use `f90-list-in-scope-vars' to pop up a buffer
giving a reasonable guess. Note this doesn't give you module
variables, or the variables of parent procedures if the current
subroutine is contained within another.
Derived types are also parsed, so that slot types of derived types
are given the correct type (rather than a UNION-TYPE) when arglist
matching. You can show the definition of a known derived type by
calling `f90-show-type-definition' which prompts (with completion)
for a typename to show.
The parser assumes you write Fortran in the style espoused in
Metcalf, Reid and Cohen. Particularly, variable declarations use a
double colon to separate the type from the name list.
Here's an example of a derived type definition
type foo
real, allocatable, dimension(:) :: a
integer, pointer :: b, c(:)
type(bar) :: d
end type
Here's a subroutine declaration
subroutine foo(a, b)
integer, intent(in) :: a
real, intent(inout), dimension(:,:) :: b
...
end subroutine foo
Local procedures whose names conflict with global ones will likely
confuse the parser. For example
subroutine foo(a, b)
...
end subroutine foo
subroutine bar(a, b)
...
call subroutine foo
...
contains
subroutine foo
...
end subroutine foo
end subroutine bar
Also not handled are overloaded operators, scalar precision
modifiers, like integer(kind=c_int), for which the precision is
just ignored, and many other aspects.
Some tests of the parser are available in f90-tests.el (in the same
repository as this file).