Indenting Fortran code in Vim
Solution 1
I've gone through a very similar process of trying to get Fortran indenting to work in vim. I still don't have it great, but I've made some progress. The script that arutaku posted (http://www.vim.org/scripts/script.php?script_id=2299) is where I started, but you need to make sure that filetype plugin indent on
is in your vimrc.
I also needed a script for determining if I was using fixed-form or free-form syntax, since in my environment I use both. This is recommended in the documentation (http://vimdoc.sourceforge.net/htmldoc/syntax.html#ft-fortran-syntax). As it specifies, I put this script in ~/.vim/ftplugin/fortran.vim
:
let s:extfname = expand("%:e")
if s:extfname ==? "f90"
let fortran_free_source=1
unlet! fortran_fixed_source
else
let fortran_fixed_source=1
unlet! fortran_free_source
endif
I also use a script so that I can press F7 to automatically complete certain constructs: http://www.vim.org/scripts/script.php?script_id=2487. I also put that in ~/.vim/ftplugin/
.
I also have these in my vimrc to try to improve things further:
let fortran_do_enddo=1
let fortran_more_precise=1
let fortran_have_tabs=1
I believe those are supposed to interact with the first script to control its behavior, but I'm not convinced that they all work for me. I know the first is supposed to properly indent do
/enddo
blocks. The issue there is that since old-style Fortran allows a do
without a matching enddo
, the script can't indent them properly unless you can guarantee that you won't use unmatched 'do' statements. The let fortran_do_enddo=1
is supposed to be that guarantee, but it doesn't seem to work for me. The last one is supposed to allow usage of the tab character, which old Fortran considered bad, so it prevents them from being marked as errors. That one appears to work for me. And to be honest, I don't remember what the middle one is supposed to do nor if it works for me.
Edit:
I discovered that there was an older version of the the first script in my vim installation directory (/usr/share/vim/vim70/indent/
in my case) to which I do not have access rights. You might have those rights, and if it's causing you problems, overwrite or delete it. If, like me, you can't edit it, you can get the version in your $HOME to overwrite the functions from the first. I did this by doing two things. First I had to remove the checks to see if the functions already exist (the statements like if exists("*FortranGetFixedIndent")
) and then I had to change all the function declarations to force overwriting by using the !
character, i.e. function! SebuFortranGetFreeIndent()
. As far as I can tell, everything now works roughly as I would expect!
Solution 2
Does gg=G work?
gg: go to top
=: indent...
G: ... until the end
Solution 3
Try: https://sourceforge.net/projects/findent/files/
From the README:
findent: indents/beautifies/converts Fortran sources
findent supports Fortran-2008
findent can convert from fixed form to free form
binaries for Unix and Windows (findent and findent.exe respectively)
wrapper for processing one or more files in one call available for Unix and Windows (wfindent and wfindent.bat respectively)
(g)vim users: findent can act as a plug-in to format your edit file with the '=' command
gui frontent available in a separate package: jfindent
Solution 4
You can use auto-indentation writing <x>==
(in command mode) where x
is the number of lines to be indented.
If vim does not have fortran indentation you can load the following plugin and try the ==
combination: http://www.vim.org/scripts/script.php?script_id=2299
armando
Updated on June 05, 2022Comments
-
armando almost 2 years
I have a fortran code which looks like this:
open(2,file=filenm(i),status='unknown') do j=1,num_lines do k=1,dime read(2,*) z(k) enddo if( j .ge. 1000 ) then do k=1,dime sumz(k)=sumz(k)+z(k) enddo nsteps=nsteps+1.0 endif enddo close(2)
as you can see the indentation is not even, I would like to have something like this:
open(2,file=filenm(i),status='unknown') do j=1,num_lines do k=1,dime read(2,*) z(k) enddo if( j .ge. 1000 ) then do k=1,dime sumz(k)=sumz(k)+z(k) enddo nsteps=nsteps+1.0 endif enddo close(2)
I can go line by line fixing the indentation but the code is kind of big. I appreciate any comment.
-
armando about 11 yearsit doesn't work properly. The "close(2)" for instance stays at the beginning of the line and all the other lines go one tab from the beginning of the line
-
armando about 11 yearsI put the script in the $HOME/.vim/after/indent/ directory. The results were similar to these with gg=G. I think the issue could be due to the fact that I don't have the Ajit J. Thakkar's Vim scripts for Fortran. I downloaded that script for fortran indent but I don't know where to put it, I mean the path. Do you have any idea?
-
happy coder about 11 years@armando, the Vim webpage tells you: install details Place the fortran.vim file in the $HOME/.vim/after/indent/ directory. In order to use this script, you must use Ajit J. Thakkar's Vim scripts for Fortran. Those should already be part of your Vim installation (in the $VIMRUNTIME directory). If not, you may find them at unb.ca/fredericton/science/chem/ajit/f_vim.htm CHEERS!
-
TomCho over 6 yearsjust for the record this answer is particularly good because it doesn't rely on any other tool (like vim and its files). In my opinion this is the best answer here by far!
-
Roel about 6 yearsFor anyone finding this in 2018: I fixed my main problem with formatting Fortran by setting "let fortran_do_enddo=1" as indicated above, on a stock Vim install - no external script needed. It might well be that the script fixes additional things or does things better, just saying that if you're a casual Fortran programmer like me and want to just fix the loop indenting behavior, this setting might be all you need.
-
knia over 2 yearsit seems
findent
was written by Willem Vermin. This answer should mention that.